rubyalgorithmruby-hash

Delete duplicated elements in an array that's a value in a hash and its corresponding ids


I have a hash with values that's an array. How do I delete repeated elements in the array and the corresponding ids in the most performant way?

Here's an example of my hash

hash = { 
  "id" => "sjfdkjfd",
  "name" => "Field Name",
  "type" => "field",
  "options" => ["Language", "Question", "Question", "Answer", "Answer"],
  "option_ids" => ["12345", "23456", "34567", "45678", "56789"]
}

The idea I have is something like this

hash["options"].each_with_index { |value, index |
  h = {}
  if h.key?(value)
    delete(value)
    delete hash["option_ids"].delete_at(index)
  else 
    h[value] = index
  end
}

The result should be

hash = { 
  "id" => "sjfdkjfd",
  "name" => "Field Name",
  "type" => "field",
  "options" => ["Language", "Question", "Answer"],
  "option_ids" => ["12345", "23456", "45678"]
}

I know I have to put into consideration that when I delete the values of the options and option_ids the indexes of those values are going to change. But not sure how to do this


Solution

  • The first idea I had is to zip the values and call uniq, then think a way to return back to the initial form:

    h['options'].zip(h['option_ids']).uniq(&:first).transpose
    #=> [["Language", "Question", "Answer"], ["12345", "23456", "45678"]]
    


    Then, via parallel assignment:

    h['options'], h['option_ids'] = h['options'].zip(h['option_ids']).uniq(&:first).transpose
    
    h #=> {"id"=>"sjfdkjfd", "name"=>"Field Name", "type"=>"field", "options"=>["Language", "Question", "Answer"], "option_ids"=>["12345", "23456", "45678"]}
    

    These are the steps:

    h['options'].zip(h['option_ids'])
    #=> [["Language", "12345"], ["Question", "23456"], ["Question", "34567"], ["Answer", "45678"], ["Answer", "56789"]]
    
    h['options'].zip(h['option_ids']).uniq(&:first)
    #=> [["Language", "12345"], ["Question", "23456"], ["Answer", "45678"]]