我试图弄清楚如何将键和值对从一个过滤器过滤到另一个过滤器
例如我想取这个哈希
x = { "one" => "one", "two" => "two", "three" => "three"}
y = x.some_function
y == { "one" => "one", "two" => "two"}
谢谢你的帮助
编辑:可能应该提到,在这个例子中,我希望它充当白名单过滤器。也就是说,我知道我想要什么,而不是我不想要什么。
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" }
这些非常好,我一直在使用它们。
也许这就是你想要的。
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 查看它的文档。
您可以只使用内置的哈希函数拒绝。
x = { "one" => "one", "two" => "two", "three" => "three"}
y = x.reject {|key,value| key == "three" }
y == { "one" => "one", "two" => "two"}
您可以将任何您想要的逻辑放入拒绝中,如果块返回 true,它将跳过新哈希中的键、值。
改进一点@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)}]
y = x.reject {|k,v| k == "three"}
结合每个人的答案,我想出了这个解决方案:
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 过滤。这将允许您编写复杂的过滤逻辑并使其易于测试。提取过滤逻辑的事实将允许在其他上下文中重用它。
前任:
x = { "one" => "one", "two" => "two", "three" => "three"}
matcher = ->(key,value) {
# FILTERING LOGIC HERE
!key[/three/]
}
x.select(&matcher) == { "one" => "one", "two" => "two"}