Techioz Blog

ハッシュ内の値である配列内の重複した要素とそれに対応する ID を削除します。

概要

配列の値を持つハッシュがあります。最もパフォーマンスの高い方法で、配列内の繰り返し要素と対応する ID を削除するにはどうすればよいですか?

これが私のハッシュの例です

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

私の考えているアイデアはこんな感じです

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
}

結果は次のようになります。

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

options と option_id の値を削除すると、それらの値のインデックスが変更されることを考慮する必要があることはわかっています。しかし、これを行う方法がわかりません

解決策

私が最初に思いついたアイデアは、値を圧縮して uniq を呼び出し、その後、最初の形式に戻る方法を考えることでした。

h['options'].zip(h['option_ids']).uniq(&:first).transpose
#=> [["Language", "Question", "Answer"], ["12345", "23456", "45678"]]
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"]}

手順は次のとおりです。

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