How to Merge Two Hashes with No New Keys

How to merge two hashes with no new keys

You could remove keys that weren't in the first hash from the second hash, then merge:

h.merge j.select { |k| h.keys.include? k }

Unlike my edited-out alternative, this is safe if you decide to change it to a merge! or update.

How to merge two hashes with same ID by combining keys with different values


hashes.
group_by { |e| [e[:id], e[:value]] }.
map { |_, g|
g.first.clone.
tap { |t|
t[:source] = g.reduce([]) { |a, e| a << e[:source] }
}
}

First group the hashes by the part that should be the same. We don't care about the key any more; but each group itself will map to something very similar to the first element of the group. Clone it so the original hashes elements are not mutated; then replace its :source with the accumulation of all the group's elements' :source values.

How can I merge two hashes without overwritten duplicate keys in Ruby?

If you have two hashes, options and defaults, and you want to merge defaults into options without overwriting existing keys, what you really want to do is the reverse: merge options into defaults:

options = defaults.merge(options)

Or, if you're using Rails you can do:

options.reverse_merge!(defaults)

Ruby - Merge two hashes and maintain ordered keys


(a.values + b.values).uniq.map.with_index{|v, i| [i.to_s, v]}.to_h
# => {"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}

Rails: How to merge two hashes if a specific key has the same value?

The following code would work for your given example.

code

result = arr.group_by {|h| h[:id]}.values.map do |arr|
arr.reduce do |h1, h2|
h1.merge(h2) do |k, ov, nv|
ov.eql?(nv) ? ov : [ov, nv].join(",")
end
end
end

p result

#=>[{:id=>77, :member_phone=>"9876543210,123456789", :created_at=>"2017-05-03T11:06:03.000Z", :name=>"Sure"}, {:id=>78, :member_phone=>"12345", :created_at=>"2017-05-03T11:06:03.000Z", :name=>"XYZ"}]

In ruby how can we merge two given hash into single hash and replace duplicate key value with greater of both the value


hash1 = { "a" => "123", "b" => "432" }

hash2 = { "a" => "439", "c" => "987" }

Code

h = hash1.merge(hash2) do |k, f, s|
f.to_i > s.to_i ? f : s
end
p h

Output

{"a"=>"439", "b"=>"432", "c"=>"987"}

Combine 2 hashes with the same key

First, I think by {"12 am"=> 0, 0} you mean a Hash with each of its keys being an hour and each value an Array with two elements, one representing the number of cleans in that hour and the other the number of lubes. If that's the case it should be like this: {"12 am"=> [0, 0]} (with [ and ] around each value)

You can do that with something like this:

@count_by_hour = @clean_by_hour.keys.each_with_object({}) do |k, h|
h[k] = [@clean_by_hour[k], @lube_by_hour[k]]
end

@count_by_hour # =>
{"12 am"=>[0, 0],
"1 am"=>[0, 0],
"2 am"=>[0, 0],
"3 am"=>[0, 0],
"4 am"=>[0, 0],
"5 am"=>[0, 0],
"6 am"=>[0, 0],
"7 am"=>[0, 0],
"8 am"=>[4, 3],
"9 am"=>[14, 4],
"10 am"=>[19, 10],
"11 am"=>[10, 14],
"12 pm"=>[19, 10],
"1 pm"=>[16, 8],
"2 pm"=>[13, 5],
"3 pm"=>[18, 20],
"4 pm"=>[7, 4],
"5 pm"=>[4, 2],
"6 pm"=>[4, 0],
"7 pm"=>[0, 0],
"8 pm"=>[0, 0],
"9 pm"=>[0, 0],
"10 pm"=>[0, 0],
"11 pm"=>[0, 0]}

You could also use a Hash for each value to improve the readability and prevent bugs: (It's easier to remember which Hash key to use than which Array index.)

@count_by_hour = @clean_by_hour.keys.each_with_object({}) do |k, h|
h[k] = { clean: @clean_by_hour[k], lube: @lube_by_hour[k] }
end

@count_by_hour # =>
{"12 am"=>{:clean=>0, :lube=>0},
"1 am"=>{:clean=>0, :lube=>0},
"2 am"=>{:clean=>0, :lube=>0},
"3 am"=>{:clean=>0, :lube=>0},
"4 am"=>{:clean=>0, :lube=>0},
"5 am"=>{:clean=>0, :lube=>0},
"6 am"=>{:clean=>0, :lube=>0},
"7 am"=>{:clean=>0, :lube=>0},
"8 am"=>{:clean=>4, :lube=>3},
"9 am"=>{:clean=>14, :lube=>4},
"10 am"=>{:clean=>19, :lube=>10},
"11 am"=>{:clean=>10, :lube=>14},
"12 pm"=>{:clean=>19, :lube=>10},
"1 pm"=>{:clean=>16, :lube=>8},
"2 pm"=>{:clean=>13, :lube=>5},
"3 pm"=>{:clean=>18, :lube=>20},
"4 pm"=>{:clean=>7, :lube=>4},
"5 pm"=>{:clean=>4, :lube=>2},
"6 pm"=>{:clean=>4, :lube=>0},
"7 pm"=>{:clean=>0, :lube=>0},
"8 pm"=>{:clean=>0, :lube=>0},
"9 pm"=>{:clean=>0, :lube=>0},
"10 pm"=>{:clean=>0, :lube=>0},
"11 pm"=>{:clean=>0, :lube=>0}}

How to merge two hashes without losing values

if the format of your hash would always look like you specified the below would work:

a = {foo: {first: 1}, bar: {first: 2}}
b = {foo: {second: 3}, bar: {second: 4}}
a.each_with_object(b) { |(k,v),x| x[k].merge!(v) }
# => {:foo=>{:second=>3, :first=>1}, :bar=>{:second=>4, :first=>2}}

Otherwise use ActiveSupport's deep_merge!



Related Topics



Leave a reply



Submit