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
Ruby - Keyword Arguments - Can You Treat All of the Keyword Arguments as a Hash? How
How to Order Files by Last Modified Time in Ruby
Millisecond Resolution of Datetime in Ruby
How to Test If a Div Has a Certain CSS Style in Rspec/Capybara
Is It a Bad Practice to List Ruby Version in Both Gemfile and .Ruby-Version Dotfile
Safely Assign Value to Nested Hash Using Hash#Dig or Lonely Operator(&.)
Heroku Rails 4 Could Not Connect to Server: Connection Refused
Can't Install Thrift Gem on Os X El Capitan
Rails - Multiple Top Level Domains and a Single Session/Cookie
Accessing Objects Memory Address in Ruby
How to Merge Two Hashes with No New Keys
Emacs Ruby-Mode Indentation Behavior
Check If Directory Is Empty in Ruby
Convert an Array to Hash, Where Keys Are the Indices
How to Sort a String's Characters Alphabetically
How to Make a Ruby String Safe for a Filesystem
Undefined Instance Method "Respond_To" in Rails 5 API Controller