【问题标题】:Ruby Hash: how to filter value (an array) and return?Ruby Hash:如何过滤值(数组)并返回?
【发布时间】:2018-03-09 16:12:49
【问题描述】:

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

我的问题:

我有以下哈希:

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

有什么帮助吗?

【问题讨论】:

    标签: ruby hash


    【解决方案1】:

    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 格式相同但没有无效电子邮件的哈希

    【讨论】:

    • @FisherCoder 不客气 ;-) 我认为解释为什么你的解决方案不起作用会更有帮助,我希望你现在有更好的理解 ^.^
    【解决方案2】:
    expanded_addresses_map.values.flatten.reject do |address|
      address[:email] !~ ::Recipient::EMAILS_REGEX
    end
    

    【讨论】:

      【解决方案3】:

      试试这个

      expanded_addresses_map.map {|k, v| v.reject { |address| address[:email] !~ ::Recipient::EMAILS_REGEX }}
      

      您必须在哈希数组中使用 map 迭代每个项目,并根据 reject 条件拒绝项目。

      【讨论】:

        【解决方案4】:

        如果您不想修改(变异)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_ 的值的说明,请参阅文档。 (为第三个局部变量选择下划线——一个有效的名称——告诉读者它没有用于块计算)。

        【讨论】:

          猜你喜欢
          • 2021-08-12
          • 2011-11-06
          • 2012-03-22
          • 2018-08-27
          • 1970-01-01
          • 2021-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多