Arrays Ruby数组#使用选项哈希进行选择以匹配

Arrays Ruby数组#使用选项哈希进行选择以匹配,arrays,ruby,Arrays,Ruby,我有一个我想搜索的哈希数组,我想写一个方法,将options哈希作为参数,并返回数组中与所有键/值对动态匹配的所有元素,我很难找到它 my_array = [ { foo: 'a', bar: 'b', baz: 'c' }, { foo: 1, bar: 2, baz: 3 }, { foo: 'A', bar: 'B', baz: 'C' }, { foo: 11, bar:

我有一个我想搜索的哈希数组,我想写一个方法,将options哈希作为参数,并返回数组中与所有键/值对动态匹配的所有元素,我很难找到它

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' }

基于类似的问题,我尝试了两种不同的方法来动态组合一个块以传递给#select,但我运气不好,也没能找到这个确切的用例。动态地#选择多个条件而只需执行#选择一次的最佳方式是什么

你可能想把这件事复杂化。这个怎么样

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"}]
my_array.define_singleton_方法(:search_by)do|opts|
self.select{h | h.values_at(*opts.keys)==opts.values}
结束
我的数组。搜索依据(foo:'a',bar:'b')
#=>[{:foo=>“a”,:bar=>“b”,:baz=>“c”}]
我的数组。搜索依据(foobar:'n')
#=> []
my_数组[{:foo=>11,:bar=>12,:baz=>13},{:foo=>11,:bar=>15,:baz=>“c”}]
您可以使用:

如果other是哈希的子集或等于哈希,则返回
true


你让我开心!我正要建议
my_array.select{| h | h.merge(finder)=h}
,但您拥有的是完美的。
my_array.select { |h| h >= finder }
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]