64

我试图弄清楚如何将键和值对从一个过滤器过滤到另一个过滤器

例如我想取这个哈希

x = { "one" => "one", "two" => "two", "three" => "three"}

y = x.some_function

y == { "one" => "one", "two" => "two"}

谢谢你的帮助

编辑:可能应该提到,在这个例子中,我希望它充当白名单过滤器。也就是说,我知道我想要什么,而不是我不想要什么。

4

7 回答 7

105

Rails 的 ActiveSupport 库还为您提供切片,除了在关键级别处理哈希:

y = x.slice("one", "two") # => { "one" => "one", "two" => "two" }
y = x.except("three")     # => { "one" => "one", "two" => "two" }
x.slice!("one", "two")    # x is now { "one" => "one", "two" => "two" }

这些非常好,我一直在使用它们。

于 2009-04-03T20:18:53.377 回答
56

也许这就是你想要的。

wanted_keys = %w[one two]
x = { "one" => "one", "two" => "two", "three" => "three"}
x.select { |key,_| wanted_keys.include? key }

包含在例如 Array 和 Hash 中的 Enumerable mixin 提供了许多有用的方法,例如 select/reject/each/etc.. 我建议您使用 ri Enumerable 查看它的文档。

于 2009-04-03T05:01:36.310 回答
49

您可以只使用内置的哈希函数拒绝。

x = { "one" => "one", "two" => "two", "three" => "three"}
y = x.reject {|key,value| key == "three" }
y == { "one" => "one", "two" => "two"}

您可以将任何您想要的逻辑放入拒绝中,如果块返回 true,它将跳过新哈希中的键、值。

于 2009-04-02T22:29:39.093 回答
8

改进一点@scottd 的答案,如果您正在使用rails 并且有您需要的列表,您可以将列表扩展为切片中的参数。例如

hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
hash.slice(*keys_whitelist)

如果没有 rails,对于任何 ruby​​ 版本,您都可以执行以下操作:

hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
Hash[hash.find_all{|k,v| keys_whitelist.include?(k)}] 
于 2013-07-18T19:56:14.733 回答
7
y = x.reject {|k,v| k == "three"}
于 2009-04-02T22:29:44.020 回答
7

结合每个人的答案,我想出了这个解决方案:

 wanted_keys = %w[one two]
 x = { "one" => "one", "two" => "two", "three" => "three"}
 x.reject { |key,_| !wanted_keys.include? key }
 =>{ "one" => "one", "two" => "two"}

谢谢你们的帮助!

编辑:

以上适用于 1.8.7+

以下适用于 1.9+ :

x.select { |key,_| Wanted_keys.include?钥匙 }

于 2009-04-03T13:04:09.740 回答
0

我会使用 lambda 过滤。这将允许您编写复杂的过滤逻辑并使其易于测试。提取过滤逻辑的事实将允许在其他上下文中重用它。

前任:

x = { "one" => "one", "two" => "two", "three" => "three"}

matcher = ->(key,value) { 
  # FILTERING LOGIC HERE 
   !key[/three/]
}

x.select(&matcher) == { "one" => "one", "two" => "two"}
于 2017-07-03T22:12:44.620 回答