Какой чистый способ сортировки хэша в Ruby без возврата массива массивов пар ключ-значение?

Когда я сортирую хэш в Ruby, он возвращает массив массивов пар ключ-значение.

Я хотел бы, чтобы он возвращал хэш.

Какой чистый способ сделать это? вводить?


person boulder_ruby    schedule 29.01.2014    source источник


Ответы (4)


Хэши на самом деле не являются сортируемыми объектами. Начиная с Ruby 1.9, они поддерживают ключи в том порядке, в котором они были добавлены, что удобно, но с точки зрения структуры данных порядок не имеет значения.

Вы можете проверить это, сравнив { a: 1, b: 2 } == { b: 2, a: 1 } #=> true. Этого нельзя сказать о массивах, в которых порядок является важной характеристикой.

Вы найдете множество методов в Ruby, которые фактически преобразуют хэши в перечисления, которые ближе к массивам в том, что они имеют определенный порядок. При возврате значения из чего-то вроде sort вы получаете массив.

Вы можете легко преобразовать его обратно в хеш, используя Hash[...]:

Hash[hash.sort(...)]
person Zach Kemp    schedule 29.01.2014
comment
Hash[...] Или метод Ruby 2.1 Array#to_h. - person steenslag; 30.01.2014

Вы можете использовать Hash#[]

h = {a: 1, b:0, c: 3}
arr = h.sort {|(_,v),(_, v2) | v <=> v2 }
h2 = Hash[arr] #=> {:b=>0, :a=>1, :c=>3}

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

person Alex.Bullard    schedule 29.01.2014

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

Предполагая, что вы хотите отсортировать значения, вот еще один способ:

h = {a: 2, b: 1, c: 4, d: 0}

Hash[h.to_a.sort_by(&:last)]
 # => {:d=>0, :b=>1, :a=>2, :c=>4} 
person Cary Swoveland    schedule 29.01.2014

Если вы хотите иметь ассоциативный массив, который внутренне отсортирован по его ключам (вместо того, чтобы вручную вставлять в правильном порядке, как в других предлагаемых решениях), вам следует взглянуть на RBTree, который реализует красно-черное дерево.

person To마SE    schedule 30.01.2014