ruby哈希白名单filter

我想弄清楚如何将一个filter中的键和值对过滤掉

例如,我想采取这个散列

x = { "one" => "one", "two" => "two", "three" => "three"} y = x.some_function y == { "one" => "one", "two" => "two"} 

谢谢你的帮助

编辑:应该提到,在这个例子中,我希望它的行为作为一个白名单filter。 也就是说,我知道我想要什么,而不是我不想要的。

也许这就是你想要的。

 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 /等等。我build议你用ri Enumerable来看看它的文档。

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

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

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

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

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

 y = x.reject {|k,v| k == "three"} 

如果你正在使用rails并且有一个你需要的列表,改进一下@scottd的答案,你可以将这个列表扩展为来自slice的参数。 例如

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

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

  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? 键}

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

例如:

 x = { "one" => "one", "two" => "two", "three" => "three"} matcher = ->(key,value) { # FILTERING LOGIC HERE !key[/three/] } x.select(&matcher) == { "one" => "one", "two" => "two"}