Ruby Hash白名单过滤器

时间:2009-04-02 22:23:58

标签: ruby hashmap

我试图找出如何将键和值对从一个过滤器过滤到另一个过滤器

例如我想采用这个哈希

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

y = x.some_function

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

感谢您的帮助

编辑:应该提一下,在这个例子中,我希望它表现为白名单过滤器。也就是说,我知道自己想要什么,而不是我不想要的东西。

7 个答案:

答案 0 :(得分:102)

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

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

答案 1 :(得分:53)

也许这就是你想要的。

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

可包含的混合物,包括在例如Array和Hash提供了许多有用的方法,比如select / reject / each / etc.我建议你看一下ri Enumerable的文档。

答案 2 :(得分:49)

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

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

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

答案 3 :(得分:8)

改进一点@scottd答案,如果您使用的是rails并且列出了您需要的内容,则可以将列表作为参数从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)}] 

答案 4 :(得分:7)

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

答案 5 :(得分: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? key}

答案 6 :(得分:0)

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

前:

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

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

x.select(&matcher) == { "one" => "one", "two" => "two"}