【问题标题】:Ruby Array#select with an options hash to match onRuby Array#select 带有要匹配的选项哈希
【发布时间】:2017-11-07 17:44:09
【问题描述】:

我有一个要搜索的哈希数组,我想编写一个方法,该方法将选项哈希作为参数并返回数组中与所有键/值对动态匹配的所有元素,我很难弄清楚。

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 的最佳方式?

【问题讨论】:

    标签: arrays ruby


    【解决方案1】:

    您可能试图将其复杂化。这个怎么样

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

    【讨论】:

      【解决方案2】:

      你可以使用Hash#&gt;=:

      如果 otherhash 的子集或等于 hash,则返回 true

      my_array.select { |h| h >= finder }
      #=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]
      

      【讨论】:

      • 你成就了我的一天!我正要建议my_array.select { |h| h.merge(finder) == h },但你所拥有的是完美的。
      猜你喜欢
      • 2020-04-30
      • 1970-01-01
      • 2014-08-26
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2022-07-06
      • 2013-05-19
      • 2021-04-23
      相关资源
      最近更新 更多