简体   繁体   中英

Combine two arrays in Ruby?

Suppose we have two arrays:

foo = [1, 2] # can be mapped in [{id: 1}, {id: 2}]
bar = [{id: 2}, {id: 4}]

As a result I need to get following array:

res = [ [1, nil], [2, {id: 2}], [nil, {id: 4}] ] 
# Is also ok [ [{id: 1}, nil], [{id: 2}, {id: 2}], [nil, {id: 4}] ]

I there any standard Ruby method to get such combinations? At first I'm looking for Ruby way, elegant, short solution.

In other words, I need to get an array diff map, which shows absent and newly added elements.

The elements:

elements = (foo + bar.map{ |h| h.values.first }).uniq
#=> [1, 2, 4]

and the combinations:

elements.map { |i| [foo.include?(i) ? i : nil, bar.include?({id: i}) ? {id: i} : nil] }
#=> [[1, nil], [2, {:id=>2}], [nil, {:id=>4}]] 

Or as Sebastian suggested, you can also use #find instead of #includes? :

elements.map { |i| [foo.find { |e| e == i }, bar.find { |e| e == { id: i } }] }

I would transform the two arrays to lookup hashes. Then collect all the ids to iterate. Map the ids into the foo and bar values, then zip them together.

foo_lookup = foo.to_h { |id| [id, {id: id}] } # change `{id: id}` into `id` for the other output
bar_lookup = bar.to_h { |item| [item[:id], item] }

ids = foo_lookup.keys | bar_lookup.keys

res = ids.map(&foo_lookup).zip(ids.map(&bar_lookup))
#=> [[{:id=>1}, nil], [{:id=>2}, {:id=>2}], [nil, {:id=>4}]]

Just another option.

foo = [1, 2]
bar = [{id: 2}, {id: 4}]
(foo + bar).group_by { |e| e.is_a?(Hash) ? e[:id] : e }.values.map { |e| e.size == 1 ? e << nil : e }
#=> [[1, nil], [2, {:id=>2}], [{:id=>4}, nil]]

The first part returns

(foo + bar).group_by { |e| e.is_a?(Hash) ? e[:id] : e }.values
#=> [[1], [2, {:id=>2}], [{:id=>4}]]

If you need to sort the sub arrays, just map using Array#unshift or Array#push (prepend or append nil ) depending in the element already there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM