我有一个我想搜索的哈希数,我想编写一种将选项作为参数的方法,并返回数组中的所有元素,以反对所有密钥/值,动态对,我很难弄清楚它。
my_array = [
{
foo: 'a',
bar: 'b',
baz: 'c'
},
{
foo: 1,
bar: 2,
baz: 3
},
{
foo: 'A',
bar: 'B',
baz: 'C'
},
{
foo: 11,
bar: 12,
baz: 13
}
]
# takes an opts hash and returns all elements for which all
# all key/value pairs match
def search_by(opts)
opts.each do |k, v|
self.select { |f| f[k] == f[v] }
end
end
my_array.search_by(foo: 'a', bar: 'b')
# should return { foo: 'a', bar: 'b', baz: 'c' }
我已经尝试了几种不同的方法来动态组成一个块以基于So的类似问题传递给#Select,但是我没有太多运气,也没有找到此确切的用例。在多个条件下动态#select的最佳方法是什么,而只需要执行#select一次?
您可以使用Hash#>=
:
返回
true
如果其他是 hash 的子集或等于 hash 。。
my_array.select { |h| h >= finder }
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]
您可能会试图使它变得复杂。怎么样
my_array = [
{foo: 'a', bar: 'b', baz: 'c'},
{foo: 1, bar: 2, baz: 3},
{foo: 'A', bar: 'B', baz: 'C'},
{foo: 11, bar: 12, baz: 13}
]
finder = {foo: 'a', bar: 'b'}
my_array.select {|h| h.values_at(*finder.keys) == finder.values }
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]
Hash#values_at
使用给定键返回适当的值,在您的情况下,这些值应与" Finder" Hash
中的这些键的值匹配。
为了明确地使其起作用您的解释方式,我们可以为my_array
定义单例方法:
my_array.define_singleton_method(:search_by) do |opts|
self.select {|h| h.values_at(*opts.keys) == opts.values}
end
my_array.search_by(foo: 'a', bar: 'b')
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]
my_array.search_by(foobar: 'n')
#=> []
my_array << {foo: 11,bar: 15,baz: 'c'}
my_array.search_by(foo: 11)
#=>[{:foo=>11, :bar=>12, :baz=>13}, {:foo=>11, :bar=>15, :baz=>"c"}]