Ruby Hash:如何过滤值(数组)并返回?

时间:2018-03-09 16:12:49

标签: ruby hash

我一直在寻找一种在Ruby Hash中过滤值的方法(我的Hash的值是一个Hashes数组)。

我的问题:

我在哈希之下:

expanded_addresses_map = 
{
  :t2p=>[],
  :non_t2p=>[
    {:recipient=>"steve sun", :email=>"ada@gmail.com"},
    {:recipient=>"sophie yan", :email=>"sophie@gmail.com"},
    {:recipient=>"eason", :email=>"eason@eason12325467com"}]
}

我想要做的是过滤掉外部哈希值中的哈希值,该哈希值包含通过我的电子邮件正则表达式过滤的无效电子邮件地址,我可以达到的最佳效果如下:

expanded_addresses_map.reject do |k, v|
  v.reject do |address|
    address[:email] !~ ::Recipient::EMAILS_REGEX
  end
end

所以我不明白的是,上面的回报让我{}

但是当我跑到下面时:

expanded_addresses_map[:non_t2p].reject do |address|
  address[:email] !~ ::Recipient::EMAILS_REGEX
end

它可以正确地返回:

[
  {:recipient=>"steve sun", :email=>"ada@gmail.com"},
  {:recipient=>"sophie yan", :email=>"sophie@gmail.com"}
]

我想得到的是:

expanded_addresses_map = 
{
  :t2p=>[],
  :non_t2p=>[
    {:recipient=>"steve sun", :email=>"ada@gmail.com"},
    {:recipient=>"sophie yan", :email=>"sophie@gmail.com"}
  ]
}

任何帮助?

4 个答案:

答案 0 :(得分:3)

reject总是返回一个对象,因此将reject嵌套在另一个对象中并不会产生预期的结果

所以代码

expanded_addresses_map.reject do |k, v|
  v.reject do |address|
    address[:email] !~ ::Recipient::EMAILS_REGEX
  end
end

在逻辑上等同于

expanded_addresses_map.reject do |k, v|
  true
end

要过滤掉map哈希值和内部过滤器的值:

expanded_addresses_map.map do |k, v|
  values = v.reject do |address|
    address[:email] !~ ::Recipient::EMAILS_REGEX
  end
  [k, values]
end.to_h

这将返回与expanded_addresses_map格式相同但没有无效电子邮件的哈希

答案 1 :(得分:2)

reject

答案 2 :(得分:0)

试试这个

c

您必须使用散列数组中的expanded_addresses_map.map {|k, v| v.reject { |address| address[:email] !~ ::Recipient::EMAILS_REGEX }} 迭代每个项目,并根据map条件拒绝项目。

答案 3 :(得分:0)

如果您不想修改(mutate)expanded_addresses_map,可以写下以下内容。

expanded_addresses_map.merge(expanded_addresses_map) { |k,v,_|
  k==:non_t2p ? v.select { |h| h[:email].match? ::Recipient::EMAILS_REGEX } : o[k] }

这使用Hash#merge的形式,它使用一个块来确定合并的两个哈希中存在的键的值,这里是所有键。请参阅文档,了解分配给三个块变量kv_的值的说明。 (第三个局部变量的下划线选择 - 一个有效的名称 - 告诉读者它没有在块计算中使用。)