【问题标题】:How to remove hashes from array based on if all keys in hash match another hash如何根据散列中的所有键是否与另一个散列匹配从数组中删除散列
【发布时间】:2023-03-24 15:57:01
【问题描述】:

我有一个哈希数组,其中每个哈希都是来自 URI::decode_www_form 的 URL 参数列表。我想删除此数组中的重复项,以便数组内的所有哈希都具有唯一的参数键。

例如,如果我有

arr = [{"update" => "1", "reload" => "true"},
       {"update" => "5", "reload" => "false"},
       {"update" => "9", "reload" => "false"},
       {"update" => "7", "reload" => "true", "newvalue" => "11111"},
       {"page" => "1"}]

我希望有一个数组只包含:

arr = [{"update" => "1", "reload" => "true"},
       {"update" => "7", "reload" => "true", "newvalue" => "11111"},
       {"page" => "1"}]

前三个条目相互重复,所以只保留其中一个,第四个是唯一的,因为它有一个额外的唯一键,前三个没有,第五个是唯一的,因为它不一样任何一个。

我将如何尝试解决这个问题?

【问题讨论】:

  • 您是如何尝试解决这个问题的?为什么你认为前三个是重复的?他们都是不同的。
  • @vgoff 他们的密钥是一样的,这就是我要删除的重复项。
  • 您可以编辑问题以澄清唯一键,而不是条目。我没有像我应该的那样依赖标题给出的提示。 :(

标签: arrays ruby hash unique


【解决方案1】:

你可以这样解决:

tmp = {}
b = arr.select do |h|
  if tmp[h.keys]
    false
  else
    tmp[h.keys] = true
    true
  end
end

【讨论】:

  • 您能否在您的答案中添加更多细节,说明它为何适用于其他读者?
  • tmp 哈希用于跟踪我们之前是否见过一组特定的键。我们遍历数组中的每个散列并使用它的键从tmp 返回一个值。如果我们得到nil,我们之前没有见过,所以我们将它设置为tmp[h.keys] = true并返回true。否则我们将返回falseArray#select 将仅返回在提供的块中返回 true 的值——具有任何唯一键集的第一个哈希。
【解决方案2】:
arr = [{"update" => "1", "reload" => "true"},
       {"update" => "5", "reload" => "false"},
       {"update" => "9", "reload" => "false"},
       {"update" => "7", "reload" => "true", "newvalue" => "11111"},
       {"page" => "1"}]

arr.uniq(&:keys)
  #=> [{"update"=>"1", "reload"=>"true"},
  #    {"update"=>"7", "reload"=>"true", "newvalue"=>"11111"},
  #    {"page"=>"1"}] 

有关uniq 占用块的情况,请参阅Array#uniq 的文档。实际上,Ruby 正在执行以下操作来确定要选择 arr 的哪些元素:

a = arr.map(&:keys) 
  #=> [["update", "reload"],
  #    ["update", "reload"],
  #    ["update", "reload"],
  #    ["update", "reload", "newvalue"],
  #    ["page"]] 

a.uniq
  #=> [["update", "reload"], ["update", "reload", "newvalue"], ["page"]]

arr.uniq(&:keys) 效果与:

arr.uniq { |h| h.keys }
  #=> [{"update"=>"1", "reload"=>"true"},
  #    {"update"=>"7", "reload"=>"true", "newvalue"=>"11111"},
  #    {"page"=>"1"}] 

许多人认为arr.uniq(&:keys) 只是用块编写上述表达式的一种简写方式。没关系,但实际上arr.uniq(&:keys)将方法(用符号表示):keys转换为proc,然后调用proc。

【讨论】:

  • 感谢您的回答,您能解释一下 &: 在这种情况下的作用吗?
猜你喜欢
  • 2011-02-03
  • 2021-02-04
  • 2015-04-16
  • 2014-01-16
  • 2015-02-03
  • 2021-11-03
  • 2013-06-17
  • 1970-01-01
  • 2015-09-18
相关资源
最近更新 更多