7stud2
(7stud --)
6 November 2012 13:06
1
Hi everyone.
I would like to merge two (or more) hashes in to one single hash.
Imagine I have the following two hashes:
foo = {"luxuy" => ["Mercedes", "BMW"], "sport" => ["porsche","ferrari"]}
bar = {"luxuy" => ["BMW", "Bentley", "Rolls Royce"],
"sport"=>["lamborghini"]}
Then this is the result I'm looking for when merging the two:
result = {"luxuy" => ["Mercedes", "BMW", "Bentley", "Rolls
Royce"],"sport" => ["porsche", "ferrari", "lamborghini"]}
Any thoughts of how to easily achieve this? I've messed around with
.merge but without any success.
Thanks!
···
--
Posted via http://www.ruby-forum.com/ .
7stud2
(7stud --)
6 November 2012 13:25
2
Hi,
this is a very special form of "merging", so I don't think there's a
built-in method for this.
But you can use the block form of Hash#merge:
···
#-------------------------------------
foo = {"luxuy" => ["Mercedes", "BMW"], "sport" => ["Ferrari"]}
bar = {"luxuy" => ["BMW", "Bentley"], "sport"=>["Lamborghini"]}
merg = foo.merge bar do |_, arr_1, arr_2|
arr_1 + arr_2
end
p merg
#-------------------------------------
--
Posted via http://www.ruby-forum.com/ .
7stud2
(7stud --)
6 November 2012 13:33
3
Off the top of my head I'd just do this:
foo.each do |one,two|
foo[one] << bar[one]
foo[one].flatten!
foo[one].uniq!
end
···
--
Posted via http://www.ruby-forum.com/ .
7stud2
(7stud --)
7 November 2012 09:26
4
Well, in this case I don't really see the advantage of using sets. The
only difference it makes is that arr_1 | arr_2 becomes
set_1.merge(set_2).
So unless you plan to actually use the special features of sets, I'd
stick with standard arrays.
But I don't want this to turn into yet another endless discussion about
implementation details, so do whatever you think fits best.
···
--
Posted via http://www.ruby-forum.com/ .
7stud2
(7stud --)
6 November 2012 13:59
5
Jan E. wrote in post #1083135:
Hi,
this is a very special form of "merging", so I don't think there's a
built-in method for this.
But you can use the block form of Hash#merge:
#-------------------------------------
foo = {"luxuy" => ["Mercedes", "BMW"], "sport" => ["Ferrari"]}
bar = {"luxuy" => ["BMW", "Bentley"], "sport"=>["Lamborghini"]}
merg = foo.merge bar do |_, arr_1, arr_2|
arr_1 | arr_2 # array union
end
p merg
#-------------------------------------
Thanks, that worked out, but I'm wondering how this applies when I have
more than 2 hashes. Because then this wouldn't work.
···
--
Posted via http://www.ruby-forum.com/\ .
7stud2
(7stud --)
7 November 2012 09:34
6
Jan E. wrote in post #1083271:
Well, in this case I don't really see the advantage of using sets. The
only difference it makes is that arr_1 | arr_2 becomes
set_1.merge(set_2).
So unless you plan to actually use the special features of sets, I'd
stick with standard arrays.
But I don't want this to turn into yet another endless discussion about
implementation details, so do whatever you think fits best.
Got the work done and stuck with the merge block approach.
···
--
Posted via http://www.ruby-forum.com/\ .
7stud2
(7stud --)
6 November 2012 14:09
7
Jermaine O. wrote in post #1083143:
Thanks, that worked out, but I'm wondering how this applies when I have
more than 2 hashes. Because then this wouldn't work.
So what? Simply merge the hashes one by one (in a loop, with
Enumerable#inject or whatever).
···
--
Posted via http://www.ruby-forum.com/\ .
Robert_K1
(Robert K.)
7 November 2012 14:03
8
Jan E. wrote in post #1083271:
> Well, in this case I don't really see the advantage of using sets. The
> only difference it makes is that arr_1 | arr_2 becomes
> set_1.merge(set_2).
>
> So unless you plan to actually use the special features of sets, I'd
> stick with standard arrays.
>
> But I don't want this to turn into yet another endless discussion about
> implementation details, so do whatever you think fits best.
Yeah. I just tend to use Set in situations where the content is supposed
to be unique - if not for efficiency reasons then for documentation.
Got the work done and stuck with the merge block approach.
Sorry, what did you mean? Are you still stuck or were you stuck?
Kind regards
robert
···
On Wed, Nov 7, 2012 at 10:34 AM, Jermaine O. <lists@ruby-forum.com> wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
7stud2
(7stud --)
6 November 2012 15:55
9
Jan E. wrote in post #1083144:
Jermaine O. wrote in post #1083143:
Thanks, that worked out, but I'm wondering how this applies when I have
more than 2 hashes. Because then this wouldn't work.
So what? Simply merge the hashes one by one (in a loop, with
Enumerable#inject or whatever).
Hi Jan, I appreciate your help but care to give an example?
···
--
Posted via http://www.ruby-forum.com/\ .
7stud2
(7stud --)
7 November 2012 14:09
10
Sorry, what did you mean? Are you still stuck or were you stuck?
Kind regards
robert
No I meant that I sticked with the approach of using the block form
of Hash#merge
···
--
Posted via http://www.ruby-forum.com/\ .
7stud2
(7stud --)
6 November 2012 16:14
11
Jermaine O. wrote in post #1083159:
Hi Jan, I appreciate your help but care to give an example?
I suppose you have an array of hashes. Define a variable for the
intermediate results and initialize it with an empty hash. Then you loop
through the hashes and merge each one with the intermediate hash:
···
#-------------------------
data = [
{luxury: ["Mercedes", "BMW"], sport: ["Ferrari"]},
{luxury: ["BMW", "Bentley"], sport: ["Lamborghini"]},
{luxury: ["something luxury"], sport: ["something sporty"]},
]
merged = {}
data.each do |cars|
merged.merge!(cars) {|_, v_1, v_2| v_1 | v_2}
end
p merged
#-------------------------
The same thing can be achieved with Enumerable#inject, which is the
generalization of this kind of "sum up the elements of a collection":
#-------------------------
merged = data.inject do |cars_1, cars_2|
cars_1.merge(cars_2) {|_, v_1, v_2| v_1 | v_2}
end
p merged
#-------------------------
--
Posted via http://www.ruby-forum.com/\ .
7stud2
(7stud --)
6 November 2012 16:29
12
The same thing can be achieved with Enumerable#inject, which is the
generalization of this kind of "sum up the elements of a collection":
Just what I need. Many thanks for this, works great. Appreciate it!
···
--
Posted via http://www.ruby-forum.com/\ .
Robert_K1
(Robert K.)
6 November 2012 22:37
13
I'd rather use Set here since apparently entries must be present only once:
require 'set'
merged = Hash.new {|h,k| h[k] = Set.new}
hashes.each do |hash|
hash.each {|k, v| merged[k].merge(v)}
end
Cheers
robert
···
On Tue, Nov 6, 2012 at 5:29 PM, Jermaine O. <lists@ruby-forum.com> wrote:
> The same thing can be achieved with Enumerable#inject, which is the
> generalization of this kind of "sum up the elements of a collection":
Just what I need. Many thanks for this, works great. Appreciate it!
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
7stud2
(7stud --)
7 November 2012 08:42
14
I'd rather use Set here since apparently entries must be present only
once:
require 'set'
Interesting, didn't knew about 'set'. Thanks.
···
--
Posted via http://www.ruby-forum.com/\ .