how can i delete a hash based on multiple values

109 Views Asked by At

I have the following list:

hash_list = 
{ "a"=>{"unit_id"=>"43", "dep_id"=>"153","_destroy"=>"false"},
  "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"},
  "c"=>{"unit_id"=>"43", "dep_id"=>"154", "_destroy"=>"false"},
  "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"}
}

I need the result as:

{
 "a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"},
 "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"},
 "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"}
}

Basically , the unit_id should not repeat. But, all _destroy=="1", entries can appear in the list.

Please help.

3

There are 3 best solutions below

6
On BEST ANSWER

Try this:

> hash_list.to_a.uniq{|_,v|v["unit_id"] unless v["_destroy"] == "1"}.to_h

#=> {
      "a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"},
      "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"},
      "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"}
    }

This will check for unit_id as uniq and also let appear "_destory" == "1" entries as you have mention.

2
On

This code:

keepers = hash_list.select { |_k, v| v["_destroy"] == "1" }.to_h
new_hash_list = hash_list.to_a.uniq { |_k, v| v["unit_id"] }.to_h
new_hash_list.merge!(keepers)

When run against this data:

hash_list = { 
  "a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"},
  "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"},
  "c"=>{"unit_id"=>"43", "dep_id"=>"154", "_destroy"=>"false"},
  "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"},
  "e"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"1"},
}

produces this result:

{
  "a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"},
  "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"},
  "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"},
  "e"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"1"},
}
0
On

Another way:

new_hash_list =
  { "a"=>{ "unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false" },
    "b"=>{ "unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"     },
    "c"=>{ "unit_id"=>"43", "dep_id"=>"154", "_destroy"=>"false" },
    "d"=>{ "unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false" },
    "e"=>{ "unit_id"=>"43", "dep_id"=>"cat", "_destroy"=>"1"     }}

require 'set'

s = Set.new
new_hash_list.each_with_object({}) do |(k,v),h|
  (h[k] = v) if v["_destroy"] == "1" || s.add?(v["unit_id"])
end
  #=> {"a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"},
  #    "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"    },
  #    "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"},
  #    "e"=>{"unit_id"=>"43", "dep_id"=>"cat", "_destroy"=>"1"    }}