1

As the title says... if I have an array containing subarrays is it possible to split the array and rename the new split arrays? I know I could simply type new_array=array[0] and so on but the problem is that the original array containing the sub arrays will vary in size.

original array...

array=[["a", "1", "2", "3"], ["b", "1", "2", "3"],  ["c", "1", "2", "3"]...]

split and renamed arrays...

array1=["a", "1", "2", "3"]
array2=["b", "1", "2", "3"] 
array3=["c", "1", "2", "3"]...

I hope that makes sense... thanks Frank

mu is too short
  • 426,620
  • 70
  • 833
  • 800
JoMojo
  • 404
  • 1
  • 7
  • 22
  • 1
    Is there an underlying real use case for this, or is this just a homework problem? I understand what you are asking, and mu is too short provided a reasonable solution, but if there's something that you are trying to accomplish that requires this, some context would be helpful. – Marc Talbot Mar 10 '12 at 06:57

2 Answers2

1

You could do some fancy-pants stuff to create a bunch of variables to hold the sub-arrays but then you'd have to do more confusing fancy-pants stuff to work the new variables. Whenever you think you want to dynamically create a bunch of variables, you usually want to create a Hash as a little portable namespace:

arrays = Hash[array.inject([]) { |m, a| m << ["array#{m.length + 1}", a] }]

That will give you this in arrays:

{
    "array1" => ["a", "1", "2", "3"],
    "array2" => ["b", "1", "2", "3"],
    "array3" => ["c", "1", "2", "3"]
}

and that's a lot easier to work with than a bunch of new variables whose names you won't know until runtime.

You could build the same structure with something simpler if you were so inclined:

arrays = { }
array.each_with_index { |a, i| arrays["array#{i + 1}"] = a }
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Thanks for your reply mu is too short... I tried your suggestion and it somewhat works but then I endup needing to retrieve the renamed arrays with arrays[]. I'm not able to use array1 for example. Keep in mind trying to manipulate arrays to this extent is very new to me. – JoMojo Mar 10 '12 at 05:27
  • @FrankN: But you can ask `arrays` which keys it has. If you created, say, an `array11` variable dynamically, how would you know which variable names you had? And once you knew you had 11 of them, you'd have do more dynamic manipulation to access the variables based only on their names. You can skip all that work by using a Hash instead of dynamically creating variables. Using a Hash also nicely avoids possible name collisions and conflicts. – mu is too short Mar 10 '12 at 05:57
  • thanks for the info. I don't know much about how hashes work but I'll look into them, maybe they're just what I need and never knew it. :) I admit that I'm a little over my head with all this but it's cool to try and learn something new and get the result wanted... – JoMojo Mar 10 '12 at 06:49
1

The only way I see to do quite literally what you are looking for is:

array=[["a", "1", "2", "3"], ["b", "1", "2", "3"],  ["c", "1", "2", "3"]]

array.each_with_index do |element, i|
  instance_variable_set "@array#{i + 1}", element
end

puts @array1 # => ["a", "1", "2", "3"]
puts @array2 # => ["b", "1", "2", "3"]

But of course, this is very ugly. Unless you absolutely need to do this, you should find a way to use your array without converting it to a list of variables. You shouldn't normally need to convert it to a hash, either - that's just converting one indexing style to another indexing style, and isn't giving you any added functionality.

Interestingly, note that this will not work, because eval (and the each block) have their own scope, which is not shared with the top-level scope:

array.each_with_index do |element, i|
  eval("array#{i + 1} = element")
end

puts array1 # => NameError
user2398029
  • 6,699
  • 8
  • 48
  • 80
  • sorry for the late reply, didn't have time till now to try this. Thanks for the help that does exactly what I asked for and you're right it is a little messy and confusing but it's the only think I could think of doing. The only other thing I can think of but don't know how to do is access the subelements of the subarrays. Example: getting the values of "a", "b", "c" either as a new array or individually. Make sense??? – JoMojo Mar 13 '12 at 00:56
  • You could just do `@array1[0]` (= "a"), `@array1[1]` (= "1"), etc. Is that what you mean? – user2398029 Mar 13 '12 at 00:59
  • No, not exactly. Using the same array example from my OP... array=[["a", "1", "2", "3"], ["b", "1", "2", "3"], ["c", "1", "2", "3"]...]. I know I can get the subarrays with array[0] which returns array[0]=["a", "1", "2", "3"]. But then how can I get the element "a" from there? Something like, array[0, 0]="a", array[0, 1]="1"... sorry if my explanation is confusing but I'm sure you're already realized that as a whole I AM confused :) – JoMojo Mar 13 '12 at 01:23
  • Then I guess you mean `array[0][0]` (="a"), `array[0][1]` (="1"), etc. ? – user2398029 Mar 13 '12 at 01:27
  • YES! Exactly!! With all the searching I did I couldn't find how to do that! I guess not knowing exactly how what it is you're searching for doesn't help :)... I hope I can make this work to get the results I need. Thanks again for your help! – JoMojo Mar 13 '12 at 01:32
  • 1
    Just noticed you're from MTL.. pretty cool, I'm from that area also. Nice to be helped by a "local" :) – JoMojo Mar 13 '12 at 01:37
  • Nice! Happy to help out a local too :) – user2398029 Mar 13 '12 at 01:58