Ruby: merge two hash as one and with value connected
h = h1.merge(h2){|key, first, second| first + " " + second }
It will work if your keys are the same. In your code, they aren't ("s1" vs "s1="). Are they supposed to be the same keys?
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.
ruby merge two hash by same key and same values
Use Hash#merge
a = {:ip=>"192.168.2.1", :b=>2}
b = {:ip=>"192.168.2.1", :c=>4}
newhash = a.merge(b)
#=> {:ip=>"192.168.2.1", :b=>2, :c=>4}
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"}]
Merge two hash arrays into one without changing Key value pairs in Ruby
Your question is still very confusing. I am assuming that you have this input:
a = [{"name" => "rihan"}, {"name" => "gihan"}, {"name" => "mihan"}]
b = [{"value" => 1}, {"value" => 2}, {"value" => 3}]
And you desire this output:
[{"name"=>"rihan", "value"=>1},
{"name"=>"gihan", "value"=>2},
{"name"=>"mihan", "value"=>3}]
Which can be achieved with:
a.zip(b).map { |ar| ar.inject(:merge) }
Or in this specific case (where the arrays after zipping are always 2-element):
a.zip(b).map { |x,y| x.merge(y) }
As
a.zip(b) #=> [[{"name"=>"rihan"}, {"value"=>1}], [{"name"=>"gihan"}, {"value"=>2}], [{"name"=>"mihan"}, {"value"=>3}]]
And then each element of the array is mapped by merging all of its elements.
Or a bit more explicit version, with a simple loop:
a.size.times.with_object([]) do |i, output|
output << a[i].merge(b[i])
end
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}}
Merge and Combine Hash Values in an Array
As others have commented, you need to show what you actually expect your output to be but I think I understand what you are looking for.
Here is a hash that I think matches the format of your hash.
my_hash = {key1: [:key1_value1, :key1_value2],key2: [:key2_value1, :key2_value2], key3: [:key3_value1, :key3_value2]}
To merge all the values just get the values, which will be a array of 2 element arrays, and then flatten that in to an single array.
my_hash.values.flatten
returns:
[:key1_value1, :key1_value2, :key2_value1, :key2_value2, :key3_value1, :key3_value2]
If you want to retain the value pairs, then just don't flatten the values.
my_hash.values
returns:
[[:key1_value1, :key1_value2], [:key2_value1, :key2_value2], [:key3_value1, :key3_value2]]
If you only want to select a subset of the entries in your has you can do something like this:
my_hash.select {|k,v| [:key1, :key2].include? k}.values.flatten
which returns:
[:key1_value1, :key1_value2, :key2_value1, :key2_value2]
The reason the following did not work is because as you saw the first select only returns the entry matching 'Apple_HLS(Media)' the second select is applied to the result of the first select which no longer includes the entry for 'Apple_HLS_Prev(Media)'
outputs['output_files'] = inputs['output_files_hash'].select{ |k,v| k == 'Apple_HLS(Media)' }.select{ |k,v| k == 'Apple_HLS_Prev(Media)' }.values
While I think what I posted (using the array include?
method) above is cleaner, you might get what you want by saying the key should be Apple_HLS(Media) OR Apple_HLS_Prev(Media)
outputs['output_files'] = inputs['output_files_hash'].select{ |k,v| k == 'Apple_HLS(Media)' || k == 'Apple_HLS_Prev(Media)'}.values
but I think this is cleaner:
outputs['output_files'] = inputs['output_files_hash'].select { |k,v| ['Apple_HLS(Media)', 'Apple_HLS_Prev(Media)'].include? k }.values
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!
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"}
Related Topics
How to Detect User Agent in Rails 3.1
How to Detect Browser Type and Its Version
Omniauth Facebook Expired Token Error
Ruby on Rails Uncapitalize First Letter
Making a Soap Request by Using Xml in Rails
Using Will_Paginate Without :Total_Entries to Improve a Lengthy Query
How Rails Delegate Method Works
Actiondispatch::Http::Uploadedfile.Content_Type Not Being Initialized in Rspec Test
Rspec: Testing Assignment of Instance Variable
Collecting Hashes into Openstruct Creates "Table" Entry
Error: While Executing Gem ... (Typeerror) Incompatible Marshal File Format (Can't Be Read)
Reversing the Order of an Array in Ruby
How to Save a Timezone Correctly with Ruby and Mongoid
How to Embed Dynamic Ruby Code to "Javascript" Section in Slim Templates
How to Globally Ignore Invalid Byte Sequences in Utf-8 Strings
How to Make a Check Box Default to Being "Checked" in Rails 1.2.3
Ruby on Rails Webpacker Can't Find Images Under Asset_Pack_Path