通过另一个哈希过滤Ruby哈希数组

时间:2014-12-23 22:04:32

标签: ruby

也许我错过了一些明显的东西。用另一个哈希或多个键/值对过滤哈希似乎很棘手。

fruit = [
  { name: "apple",   color: "red",    pieable: true  },
  { name: "orange",  color: "orange", pieable: false },
  { name: "grape",   color: "purple", pieable: false },
  { name: "cherry",  color: "red",    pieable: true  },
  { name: "banana",  color: "yellow", pieable: true  },
  { name: "tomato",  color: "red",    pieable: false }
]
filter = { color: "red", pieable: true }

# some awesome one-liner? would return
[
  { name: "apple",   color: "red",    pieable: true  },
  { name: "cherry",  color: "red",    pieable: true  }
]      

我不认为是哈希数组的问题。我甚至不知道如何通过另一个任意哈希测试哈希。我正在使用Rails,所以没有active_support等任何东西都可以。

6 个答案:

答案 0 :(得分:2)

可以制成一个衬里。但多线更清洁。

fruit.select do |hash| # or use select!
  filter.all? do |key, value|
    value == hash[key]
  end
end

答案 1 :(得分:1)

如果你允许两条线,它也可以制成一个有效的"单线"像这样:

keys, values = filter.to_a.transpose 
fruit.select { |f| f.values_at(*keys) == values }

答案 2 :(得分:1)

效率最高(您可以使用filter的数组形式来避免重复转换),但是:

fruit.select {|f| (filter.to_a - f.to_a).empty? }

答案 3 :(得分:1)

我倾向于使用Enumerable#group_by

fruit.group_by { |g| { color: g[:color], pieable: g[:pieable] } }[filter]
  #=> [{:name=>"apple",  :color=>"red", :pieable=>true},
  #    {:name=>"cherry", :color=>"red", :pieable=>true}]

答案 4 :(得分:0)

Tony Arcieri(@bascule)在twitter上提供了这个非常好的解决方案。

require 'active_support/core_ext'  # unneeded if you are in a rails app
fruit.select { |hash| hash.slice(*filter.keys) == filter }

它有效。

# [{:name=>"apple", :color=>"red", :pieable=>true},
# {:name=>"cherry", :color=>"red", :pieable=>true}]

答案 5 :(得分:0)

试试这个

<i>