如果值重复,则从哈希散列中删除哈希
我有哈希的哈希
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"} } } }