Ju Nogueira
Ju Nogueira

Reputation: 8461

Concatenate arrays items

I have two arrays:

x = [ ["0", "#0"], ["1", "#1"] ]
y = [ ["00", "00 description"], ["10", "10 description"] ]

What i need is to merge them so i get the following as result:

result = [ ["000", "#0 00 description"], ["010", "#0 10 description"],
   ["100", "#1 00 description"], ["110", "#1 10 description"] ]

Is there a method for that? Or I'll need to use collect or something like this?

Thanks in advance.

Upvotes: 2

Views: 1067

Answers (3)

Mladen Jablanović
Mladen Jablanović

Reputation: 44110

You can use Array#product method:

x = [ ['0', "#0"], ['1', "#1"] ]
#=> [["0", "#0"], ["1", "#1"]]
y = [ ['00', "00 description"], ['10', "10 description"] ]
#=> [["00", "00 description"], ["10", "10 description"]]
x.product(y).map{|a1,a2| [a1[0]+a2[0], a1[1] + ' ' + a2[1]]}
#=> [["000", "#0 00 description"], ["010", "#0 10 description"], ["100", "#1 00 description"], ["110", "#1 10 description"]]

And if you wouldn't need different kinds of concatenation above (second one is inserting space between), even:

x.product(y).map{|a1,a2|
  a1.zip(a2).map{|e|
    e.inject(&:+)
  }
}

And here's a variant without Array#product, admittedly less readable:

x.inject([]){|a,xe|
  a + y.map{|ye|
    xe.zip(ye).map{|e|
      e.inject(&:+)
    }
  }
}

Upvotes: 1

Arkku
Arkku

Reputation: 42159

In your example you seem to be applying special rules for concatenating the digits of specific decimal representations of integers, which doesn't work in any simple manner (e.g. when you write 00 it's just 0 to the interpreter). However, assuming simple string concatenation is what you meant:

x = [ ["0", "#0"], ["1", "#1"] ]
y = [ ["00", "00 description"], ["10", "10 description"] ]
z = []
x.each do |a|
  y.each do |b|
    c = []
    a.each_index { |i| c[i] = a[i] + b[i] }
    z << c
  end
end
p z

Edit: The originally posted version of the question had integers as the first elements of each sub-array, the preface to the solution refers to that. The question has since been edited to have strings as assumed here.

Upvotes: 2

glenn mcdonald
glenn mcdonald

Reputation: 15488

In your example you're concatenating the first elements without spaces, but the second elements with spaces. If you can do them both the same way, this can be just:

x.product(y).map {|a,b| a.zip(b).map(&:join)}
=> [["000", "#000 description"], ["010", "#010 description"], ["100", "#100 description"], ["110", "#110 description"]]

If the different concatenations are required, this'll do:

x.product(y).map {|a,b| [a[0]+b[0],a[1]+' '+b[1]]}
=> [["000", "#0 00 description"], ["010", "#0 10 description"], ["100", "#1 00 description"], ["110", "#1 10 description"]]

Upvotes: 1

Related Questions