gqweg
gqweg

Reputation: 85

how can you loop through multiple arrays parallel?

i have 4 arrays.

["one", "two", "three"]
["1", "2", "3"
["un", "deux", "trois"]
["ichi", "ni", "san"]

is it possible to concatenate each element in their respective arrays ?

so i end up with single lines of string like like

"one, 1, un, ichi"\n
"two,2, deux,ni"\n

and so on...

is it possible to do this in one loop ?

for i in (1..array1.count)

puts array1[i] + ", " + array2[i] + ", " + array3[i] + ", " + array4[i]

end

What happens when there might be unpredictable number of arrays & they are each unequal size?

Upvotes: 8

Views: 5495

Answers (4)

Filipe Miguel Fonseca
Filipe Miguel Fonseca

Reputation: 6436

If you are using ruby 1.9 maybe you can take advantage of external iterators, this will let you deal with any number of arrays:

array1 = ['one','two','three']
array2 = [1,2,3,4]
array3 = ['un','deux','trois']
array4 = ['ichi','ni','san']

def bundle(*enumerables)
  enumerators = enumerables.map{ |e| e.to_enum }
  loop { puts enumerators.map { |e| e.next }.join(', ') }
end

bundle(array1,array2,array3,array4)

produces:

one, 1, un, ichi
two, 2, deux, ni
three, 3, trois, san

Upvotes: 1

glenn mcdonald
glenn mcdonald

Reputation: 15488

Easy:

a = [array1,array2,array3,array4] # or however many you have

puts a.transpose.map {|x| x.join(", ")}.join("\n")

This will work with any number of subarrays as long as they are all the same size (regardless of what that size is).

If the subarrays are different lengths, but it's OK to use the length of the first one, you can do this:

a[0].zip(*a[1..-1]).map {|x| x.join(", ")}.join("\n")

Upvotes: 5

Chris Lutz
Chris Lutz

Reputation: 75399

I would use Enumerable#zip to create an array of arrays. It will create an array where the first element is an array of the first elements of all the arrays you pass to it, and so on with the second, third, etc. Then go through this list and print each argument using Array#join. Something like:

a.zip(b, c, d).each do |l|
  puts l.join(", ")
end

EDIT: No, zip won't be very helpful as far as appending arrays goes. glenn's method is good for that. You can append to the end of a zipped array, but it's not as easy:

e = a.zip(b, c)
e.length.times { |i| e[i].push(d[i]) }

Upvotes: 3

Robert Massaioli
Robert Massaioli

Reputation: 13477

Well if you know that they were all the same length:

(0...array1.length).each{|i|puts array1[i] + ", " + array2[i] + ", " + array3[i] + ", " + array4[i]}

Edit: The Following code works

array1 = ["one", "two", "three"]
array2 = ["1", "2", "3"]
array3 = ["un", "deux", "trois"]
array4 = ["ichi", "ni", "san"]

(0...array1.length).each{|i| puts array1[i] + ", " + array2[i] + ", " + array3[i] + ", " + array4[i]}

Edit2: what happens if you dont know how many arrays there will be?

I would suggest making an array of arrays; a list of arrays. Make an array of arrays (essentially a 2D array but it can't be indexed like one) and with it print every line one by one for each array in the arrayList.

This code works:

array1 = ["one", "two", "three"]
array2 = ["1", "2", "3"]
array3 = ["un", "deux", "trois"]
array4 = ["ichi", "ni", "san"]

arrayList = []
arrayList.push(array1, array2, array3, array4)

p arrayList

(0...array1.length).each{|i|
    (0...arrayList.length).each{|j|
        print arrayList[j][i] + ", "
    }
    print "\n"
}

Upvotes: 4

Related Questions