Rails:从散列数组中删除元素

24

我有以下数组:

 array = [{"email"=>"test@test.com", "name"=>"Test"},
          {"email"=>"testA@test.com", "name"=>"Test A"},
          {"name"=>"Test B", "email"=>"testB@test.com"},
          {"email"=>"testC@test.com", "name"=>"Test C"},
          {"name"=>"Test D", "email"=>"testD@test.com"},
          {"email"=>"testE@test.com"},
          {"name"=>"Test F", "email"=>"testF@test.com"}]

我有一个“黑名单”电子邮件列表,例如:

 blacklist = ["testC@test.com"]

我想要做这样的事情:

 array - blacklist 
 # => should remove element {"email"=>"testC@test.com", "name"=>"Test C"} 

肯定有一种优雅的 Ruby 方式可以使用 .select 或其他东西来实现这个,但我还没能搞清楚。我试过以下代码但无效:

 array.select {|k,v| v != "testC@test.com"} # => returns array without any changes
2个回答

54

我认为你正在寻找这个:

filtered_array = array.reject { |h| blacklist.include? h['email'] }

如果你想使用select而不是reject(也许你不想伤害任何人的感情):

filtered_array = array.select { |h| !blacklist.include? h['email'] }

你的

array.select {|k,v| ...

由于数组将单个元素传递给可枚举块,因此尝试不起作用,在这种情况下,该元素将是哈希。如果array的元素是两个元素的数组,则|k,v|技巧可以发挥作用。


太棒了!谢谢您的快速响应 :) 事实上,你回答得如此之快,以至于我甚至无法在 Stack Overflow 的系统中“接受”这个答案。 - MorningHacker
1
还有一个排除函数,它是!include的别名。 - Darren Cato
@Darren:唯一的缺点是exclude?是Rails扩展,这会导致双重否定的领域:) 我可能会选择reject/include? - mu is too short

2
如何呢?
array.delete_if {|key, value| value == "testC@test.com" } 

4
与@mu is too short的select类似,应该使用array.delete_if {|hash| hash["email"] == "testC@test.com"} - PeterWong
delete_if 在原地进行操作(通常不是一个好主意),OP 似乎想要一个新的数组。 - tokland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接