hey mike
hey mike

Reputation: 2471

ruby language - merge an array into another by finding same element

A = [
  { :id => 1, :name => 'good', :link => nil },
  { :id => 2, :name => 'bad', :link => nil } 
]

B = [
  { :id => 3, :name => 'good' },
  { :id => 4, :name => 'good' }, 
  { :id => 5, :name => 'bad' } 
]

I need to merge array B into A so that :link in array A includes the entry in array B if :name is the same value in each array.

For example, after processing array A should be:

A = [
  { :id => 1, :name => 'good', :link => [{ :id => 3, :name => 'good' }, { :id => 4, :name => 'good' }] },
  { :id => 2, :name => 'bad', :link => [{ :id => 5, :name => 'bad' }] }
]

thanks.

Upvotes: 0

Views: 162

Answers (3)

tokland
tokland

Reputation: 67850

Functional approach:

B_grouped = B.group_by { |h| h[:name]  }
A2 = A.map { |h| h.merge(:link => B_grouped[h[:name]]) }
#=> [{:link=>[{:name=>"good", :id=>3}, {:name=>"good", :id=>4}], :name=>"good", :id=>1},
#    {:link=>[{:name=>"bad", :id=>5}], :name=>"bad", :id=>2}]

Upvotes: 0

Joachim Isaksson
Joachim Isaksson

Reputation: 180897

The short version;

a.each { | item | item[:link] = b.find_all { | x | x[:name] == item[:name] } }

Demo here.

Upvotes: 3

megas
megas

Reputation: 21791

In ruby the constants begin with an uppercase letter, so you should use lowercase letter: A => a, B => b

a.each do |ha|
  b.each do |hb|
    if ha[:name] == hb[:name]
      ha[:link] |= []
      ha[:link] << hb
    end
  end
end

Upvotes: 1

Related Questions