tags:

views:

113

answers:

4

Given an array arr = [['a', '1'], ['b','2'], ['c', '3']]

Whats the best way to split it into 2 arrays

eg:

first = ['a','b','c'] and

second = ['1', '2', '3'] ..can i do this via a collect?

+1  A: 
arr = [['a', '1'], ['b','2'], ['c', '3']]

a = []
b = []

arr.each{ |i| a << i[0]; b << i[1] }
Nikolaus Gradwohl
hmm ok i just stumbled upon arr.trasposearr = [['a', '1'], ['b','2'], ['c', '3']].transposefirst = arr[0]second = arr[1]i wonder which is more effecient
Ray Dookie
i think it won't matter for 3 items :-)try some timing tests using larger items and some data that resembles your real data
Nikolaus Gradwohl
A: 

You can do this via collect (an alias of map), but not in a single operation, because map/collect always returns a single Array. You could do

first = arr.map { |element| element[0] }   
second = arr.map { |element| element[1] }

which has the disadvantage of iterating over arr twice. However, that shouldn't normally be a problem, unless you are dealing with a large amount of elements or this operation has to run a large number of times.

Confusion
+3  A: 

Using the zip method is quite elegant as well:

arr[0].zip *arr[1..-1]
first = arr[0]
second = arr[1]
You
...this is pretty much the same thing as doing arr.transpose, though.
You
+8  A: 

ok i just stumbled upon arr.traspose

arr = [['a', '1'], ['b','2'], ['c', '3']].transpose

first = arr[0]

second = arr[1]

compared to the answers above arr.zip, arr.map, and the foreach, which is more efficient? Or which is the most elegant solution?

OR (Thanks to comment by Jörg W Mittag - see comment below) first, second = arr.transpose

Ray Dookie
Transpose is the most elegant solution IMHO (but I'm a mathematician). I am unsure of which is the most efficient, but I'd wager that zip, transpose and foreach are pretty much the same, and map is slightly slower. Foreach will have an advantage if you don't want all of the elements in each row (e.g. two out of three or something).
You
This is basically the whole point of transpose, so it is almost guaranteed to be the most efficient. The others have slightly more moving parts, which usually leads to sightly less efficiency. I doubt the difference is usually that huge. The transpose method is certainly the most readable, though, so that would be its biggest plus in my book. (I'm always reluctant to say one method *is the most efficient, period*, because performance quirks in different versions of Ruby will usually make a liar of me someday.)
Chuck
You can use destructuring bind: `first, second = arr.transpose`. Much more elegant. And since we are waxing on performance here: the JRuby team is working on an aggressively optimizing compiler which can eliminate the intermediate arrays when using destructuring bind, multiple assignments, multiple return values, splat arguments and the like. (In fact, the compiler is so good that its author has asked them to rewrite some of the Java portions of JRuby in Ruby because it would actually be faster.)
Jörg W Mittag