Обратный хеш в Ruby

Как бы я изменил элементы в хэше, сохранив те же значения и ключи, но изменив их порядок в хэше.

Вот так:

{ "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }

И преобразовать это в:

{ "1" => "spider", "lala" => "54", "10" => "cool", "4" => "happiness" }

Или, возможно, я мог бы запуститьeach цикл назад, начиная с последнего элемента в хэше, а не с первого?

 mahemoff06 мар. 2013 г., 04:47
Не путать с инвертированием хеша (переключение ключей со значениями).ruby-doc.org/core-2.0/Hash.html#method-i-invert

Ответы на вопрос(9)

hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
reversed_hash = Hash[hash.to_a.reverse]

reduce а такжеmerge чтобы добавить элемент в начало нового хэша:

hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
hash.reduce({}){ |memo, object| Hash[*object].merge(memo) }

но это безумие: D

reversed_h = Hash[h.to_a.collect(&:reverse)]
 16 апр. 2013 г., 05:15
Почему не простоHash[h.map { |k, v| [v, k] }] или жеHash[h.map(&:reverse)] затем?
h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
p Hash[h.reverse_each.map{|e| e}]
#=> {"1"=>"spider", "lala"=>"54", "10"=>"cool", "4"=>"happiness"}

которые отлично работают, как этот). Если вам нужно сделать это, это может указывать на то, что хэш был не лучшим выбором.

 04 июн. 2012 г., 01:48
+1 за "хэш" не может быть лучшим выбором " предостережение.
Решение Вопроса

перевернуть его и затем преобразовать обратно в Hash:

reversed_h = Hash[h.to_a.reverse]

Hash#to_a дает вам массив массивов, внутренние массивы просты[key,value] пар, затем вы обращаете этот массив с помощьюArray#reverse, а такжеHash[] преобразует[key,value] пары обратно в хэш.

Ruby 2.1 добавляетArray#to_h метод, так что теперь вы можете сказать:

reversed_h = h.to_a.reverse.to_h
 16 апр. 2013 г., 04:32
reversed_h = Hash [h.to_a.collect (& amp;: reverse)]
 29 июн. 2013 г., 19:42
{"счастье" = "4", "круто" = "10", "54" = "лала", "паук" = ">" 1 "Hash[h.to_a.map {|x| x=x.reverse}]
 16 апр. 2013 г., 05:11
@ P.S.V.R: Кажется, что есть некоторая путаница между текстом вопроса ("переверните элементы в хэше, сохраняяsame values and keys, но поменять их порядок в хэше & quot; [выделение мое]) и приведенный пример. Очевидно, что текст в вопросе был верным, иначе Слив принял бы вместо этого ответ Стинслага.
 29 июн. 2013 г., 19:41
Спасибо, это дает мне подсказку сделать это:{"happiness"=>"4", "cool"=>"10", "54"=>"lala", "spider"=>"1"}
 16 апр. 2013 г., 05:26
Спасибо за указание на это. Это я был виноват.

reverse_each а такжеto_h:

{foo: 1, bar: 2}.reverse_each.to_h
#=> {:bar=>2, :foo=>1}
 26 авг. 2015 г., 07:52
Хорошо, нет временного массива, которыйreverse будет производить. [Массив # to_h] (ruby-doc.org/core-2.2.3/Array.html#method-i-to_h пришли с v 2.1, ноEnumerable#reverse_each был вокруг, по крайней мере, v1.9.3. С другой стороны,h.reverse_each.with_object({}) } |(k,v),g| g[k]=v }.

hash.map(&:reverse).to_h или жеhash.reverse_each.to_h

В рельсах вы можете сделать этоhash.invert

Ruby 1.8.7задокументировано, что порядок элементов в хэше не находится под нашим контролем, поэтому ни один из вышеперечисленных методов не работает. Ruby 1.9.3все работает и документируется так, как полагаются другие ответы.

$ irb1.8
h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
Hash[h.to_a().reverse()]
=> {"lala"=>"54", "1"=>"spider", "10"=>"cool", "4"=>"happiness"}
quit
$ irb1.9.1
h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
Hash[h.to_a().reverse()]
=>{"1"=>"spider", "lala"=>"54", "10"=>"cool", "4"=>"happiness"}

Способ Ruby 1.8.7 был укоренен для меня настолько прочно, что я довольно долго не понимал вопрос. Я думал, что просил способHash # инвертный: т.е. чтобы преобразовать хеш так, чтобы диапазон соответствовал домену. Этот метод отбрасывает дубликаты. Лу Рамальхо предлагаетметод это не так, но это немного неуклюже. Это немного короче:

$ irb
def invertWithDuplicates(original)
  inverse = Hash.new() { |hash, key| hash[key] = []; }
  original.each_pair() { |key, value| inverse[value].push(key); }
  return inverse
end
h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "cool" }
invertWithDuplicates(h)
=> {"happiness"=>["4"], "cool"=>["1", "10"], "54"=>["lala"]}

Извините, что отошел от темы, предназначенной для OP, хотя я утверждаю, что это соответствует заголовку поста "Отменить хэш в Ruby".

 09 окт. 2013 г., 04:05
Это лучший ответ на данный момент. Фактически, я предполагаю, что в большинстве языков нет никакой гарантии порядка ключей. Ключи - это набор, а не список. Это важно иметь в виду. Это настолько распространено, что я никогда не буду использовать какие-либо методы на этой странице. Вместо этого я упорядочиваю хеш по мере необходимости в зависимости от потребностей представления.

hash = {:a => :x, :b => :y, :c => :y, :d => :z}

чтобы:

{:x => [:a], :y => [:b, c], :z => [:d] }

Можно:

h={};hash.to_a.each{|e|h[e[1]]||=[];h[e[1]]<<e[0]};h

Ваш ответ на вопрос