如何根据散列中的所有键是否与另一个散列匹配来从数组中删除散列

时间:2016-07-09 19:55:13

标签: arrays ruby hash unique

我有一个哈希数组,其中每个哈希都是来自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"}]

如果前三个条目彼此重复,那么只保留其中一个,第四个是唯一的,因为它有一个额外的唯一密钥,前三个没有,第五个是唯一的,因为它不同于他们中的任何一个。

我将如何尝试解决此问题?

2 个答案:

答案 0 :(得分:1)

你可以这样解决:

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

答案 1 :(得分:1)

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。