#ruby #hash
#ruby #хэш
Вопрос:
Как бы вы поступили с удалением дубликатов на основе ключа?
values = [{"a"=>"1"}, {"a"=>"2"}, {"b"=>"1"}, {"a"=>"4"}]
Как я могу игнорировать значение и запускать uniq
на основе ключа, чтобы он возвращал:
[{'a' => '1'}, {'b' => '1'}]
Комментарии:
1. @sawa, работающий под управлением 1.8.7, мой irb принял их просто отлично, но я обновил сообщение, чтобы все было менее запутанным.
2. Ладно, извините. Ваше предположение верно. Я использую ruby1.9.2.
Ответ №1:
Предполагая, что вам все равно, какое значение будет заблокировано, просто запустите их в хэш (который имеет уникальные ключи и поэтому, вероятно, является подходящим классом коллекции для этого случая):
h = {}
values.each{|i|i.each{|k,v|h[k] = v}}
puts h # => {"a"=>"4", "b"=>"1"}
… или, если вы хотите, чтобы первый из каждого ключа:
h = {}
values.each{|i|i.each{|k,v|h[k] = v unless h[k]}}
Если вы хотите вернуться к массиву:
h.each{|k,v|a << {k=>v}}
Ответ №2:
Следующее будет работать только в ruby 1.9, так что это может быть бесполезно.
Hash[values.map(amp;:first).reverse].map{|a| Hash[*a]}
Если вам это нужно в исходном порядке,
values amp; Hash[values.map(amp;:first).reverse].map{|a| Hash[*a]}
Ответ №3:
Без введения каких-либо промежуточных переменных следующая строка 1 сделает свое дело:
> [{"a"=>"1"}, {"a"=>"2"}, {"b"=>"1"}, {"a"=>"4"}].inject({}) {|s,h| s.merge(h) unless s.keys.include? h.keys}.inject([]) {|s,h| s << {h[0]=>h[1]}}
=> [{"a"=>"4"}, {"b"=>"1"}]