Ruby Array#选择具有匹配的选项哈希选择



我有一个我想搜索的哈希数,我想编写一种将选项作为参数的方法,并返回数组中的所有元素,以反对所有密钥/值,动态对,我很难弄清楚它。

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"}]

最新更新