0

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.

1
  • 2
    Based on what multiple values?? What is the logic behind removing "c" from the result hash? Commented Jun 8, 2015 at 9:15

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

6 Comments

There's a bug here: Only one element having _destroy == 1 will be retained. The others will be deleted.
@WayneConrad : let me check
@WayneConrad is well-known as a spoil-sport. He's saying that v["unit_id"] unless v["_destroy"] == "1" #=> nil for all values h for which h["_destroy"] #=> "1", so uniq will keep only the first of those. Regretfully, I don't see a fix.
@WayneConrad, anyone who spotted the problem would have been the spoil-sport, considering that Gagan had what seemed like an admirable answer. It was a good catch. I was only making jest. :-)
@CarySwoveland Oh, humor! Earth creatures always get me with humor. :)
|
1

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"},
}

2 Comments

I almost didn't upvote because of that misaligned "_destroy"=>"false". The outer braces are also unconventional. In future, please show more respect for readers' sensibilities.
Alternatively, keepers, no_dups = new_hash_list.partition { |_k, v| v["_destroy"] == "1" }; no_dups.uniq! { |_k,h| h["unit_id"] }; keepers.concat(no_dups).to_h. The last line could instead be keepers.to_h.update(no_dups.to_h).
0

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"    }} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.