如果值重复,则从哈希散列中删除哈希

我有哈希的哈希

params = {collection_permissions_attributes: {'0' => {:collection_id => '1'}, '2' => {:collection_id => '1'}, '3' => {:collection_id => '4'}}} 

如何从collection_permissions_attributes项中完全删除哪个哈希包含重复值? 所以从上面的哈希我想:

 params = { collection_permissions_attributes: {'0' => {:collection_id => '1'}, '3' => {:collection_id => '4'}}} 

提前致谢!

这是另一种方式,但它需要Ruby 1.9+,因为它取决于散列元素的顺序。

 newams = {collection: ams[:collection].sort.reverse.to_h.invert.invert} #=> {:collection=>{"3"=>{:collection_id=>"4"}, "0"=>{:collection_id=>"1"}}} 

如果由于某种原因希望散列元素按键顺序,则可以通过添加更多操作来实现,如“说明”部分末尾所述。

说明

 ams = {collection: {'0' => {:collection_id => '1'}, '2' => {:collection_id => '1'}, '3' => {:collection_id => '4'}}} 

首先,按降序键顺序对哈希元素重新排序,这样当两个或多个元素具有相同的值时,将只保留具有最小键值的元素。 要执行此操作然后重新构建哈希,需要执行以下三个步骤:

 a = ams[:collection].sort #=> [["0", {:collection_id=>"1"}], ["2", {:collection_id=>"1"}], # ["3", {:collection_id=>"4"}]] b = a.reverse #=> [["3", {:collection_id=>"4"}], ["2", {:collection_id=>"1"}], # ["0", {:collection_id=>"1"}]] c = b.to_h #=> {"3"=>{:collection_id=>"4"}, "2"=>{:collection_id=>"1"}, # "0"=>{:collection_id=>"1"}} 

接下来,我们反转哈希,使键值和值键。 因为哈希不能有重复的键,这消除了重复:

 d = c.invert #=> {{:collection_id=>"4"}=>"3", {:collection_id=>"1"}=>"0"} 

最后,倒退:

 e = d.invert #=> {"3"=>{:collection_id=>"4"}, "0"=>{:collection_id=>"1"}} 

哈希元素可以按键顺序重新排序(如果需要),如下所示:

 e.to_a.reverse.to_h #=> {"0"=>{:collection_id=>"1"}, "3"=>{:collection_id=>"4"}} 

我可以想到如下:

 params = { :employee => {collection_permissions_attributes: {'0' => {:collection_id => '1'}, '2' => {:collection_id => '1'}, '3' => {:collection_id => '4'}}} } hash = Hash[params[:employee][:collection_permissions_attributes].group_by do |k,v| v[:collection_id] end.map { |_,v| v.first }] params[:employee][:collection_permissions_attributes] = hash 

产量

 {:employee => {:collection_permissions_attributes => { "0"=>{:collection_id=>"1"}, "3"=>{:collection_id=>"4"} } } }