Reputation: 2854
Given that I have an array of hashes abc
and a hash ghi
:
abc = [{
'a' => '1',
'b' => '2',
'c' => '3',
'd' => '4'
}]
ghi = {
'a' => '1',
'b' => '2'
}
what is the cleanest and most efficient way of selecting hashes from abc
that contain all of the key-value pairs in ghi
?
I was able to do this:
abc.map {|n| n.slice(*ghi.keys) == ghi }.all?
although it doesn't look very clean.
Upvotes: 2
Views: 1498
Reputation: 908
abc.select{|h| ghi.all?{|k,v| h.key?(k) && h.value?(v) } }
Benchmark result:
require 'benchmark'
Benchmark.bm do |x|
x.report { 10000.times { abc.select{|h| ghi.all?{|k,v| h.key?(k) && h.value?(v) } } } }
x.report { 10000.times { abc.select{|h| h.merge(ghi) == h } } }
x.report { 10000.times { abc.select{|hash| (ghi.to_a - hash.to_a).empty? } } }
x.report { 10000.times { abc.select{|hash| (hash.values <=> ghi.values) == (hash.keys <=> ghi.keys) } } }
end
user system total real
0.040000 0.000000 0.040000 ( 0.037253)
0.040000 0.000000 0.040000 ( 0.046138)
0.150000 0.000000 0.150000 ( 0.155893)
0.020000 0.000000 0.020000 ( 0.028176)
Looks like Rajarshi's answer is the most efficient among all the answers.
Upvotes: 0
Reputation: 12330
For all keys and values check, you can try:
abc = [
{
'a' => '1',
'b' => '2',
'c' => '3',
'd' => '4'
},
{
'a' => '33',
'b' => '23'
}
]
d = {
'a' => '1',
'b' => '2'
}
abc.select{|hash| ((hash.values <=> d.values) == 1 ) && ((hash.keys <=> d.keys) == 1 )}
# => [{"a"=>"1", "b"=>"2", "c"=>"3", "d"=>"4"}]
Upvotes: 0
Reputation: 168131
In Ruby 2.3.
abc.select{|h| h >= ghi}
Note: This was answered before the OP mentioned the Ruby version.
Prior versions of Ruby:
abc.select{|h| h.merge(ghi) == h}
Upvotes: 8
Reputation: 6603
Not sure if this is the fastest.
abc.select{|hash| (ghi.to_a - hash.to_a).empty?}
Upvotes: 2