通过sort / sort_by方式改变哈希键的方法是否存在?

4

我目前正在解决一个问题,试图将前者转换为后者。

{ a: 2, b: 5, c: 1 } => { a: 1, b: 2, c: 5 }

尝试使用以下方法实现此操作:

hash = { a: 2, b: 5, c: 1 }.sort_by {|k,v| v}.to_h

这将得到这个 => {:c=>1, :a=>2, :b=>5}

如何在排序值的同时更改哈希表的键?


1
@lurker 近期的 Ruby 哈希表是有序的,它们保持插入顺序,就像 JavaScript 对象一样(当然是指最近版本的 JavaScript)。 - mu is too short
@muistooshort 好的,谢谢,我之前不知道这个。 - lurker
4个回答

1

看起来你正在尝试将哈希分成键和值,分别对它们进行排序,然后将它们作为哈希重新组合。

在这种情况下,你可以像这样做:

hash.to_a.transpose.map(&:sort).transpose.to_h

逐步执行的步骤如下:
# First array-ify the hash into key/value pairs
hash.to_a
# [[:a, 2], [:b, 5], [:c, 1]] 

# Then transpose to group the keys and values together
hash.to_a.transpose
# [[:a, :b, :c], [2, 5, 1]]

# Then sort the keys and values separately
hash.to_a.transpose.map(&:sort)
# [[:a, :b, :c], [1, 2, 5]] 

# And transpose again to get key/value pairs
hash.to_a.transpose.map(&:sort).transpose
# [[:a, 1], [:b, 2], [:c, 5]] 

# And combine the array of key/value pairs into a hash
hash.to_a.transpose.map(&:sort).transpose.to_h
# {:a=>1, :b=>2, :c=>5} 

您也可以手动执行hash.to_a.transpose步骤,如下所示:

[hash.keys, hash.values].map(&:sort).transpose.to_h

你甚至不需要假设#keys#values会按任何特定顺序生成数组,因为你无论如何都在排序。

1
以下方法怎么样?
{ a: 2, b: 5, c: 1 }.then { |hash| [hash.keys.sort, hash.values.sort].transpose }.to_h


1
h = { a: 2, b: 5, c: 1 }

a = h.values.sort
  #=> [1, 2, 5] 
h.transform_values { a.shift }
  #=> {:a=>1, :b=>2, :c=>5} 

请看 Hash#transform_values

0
hash.keys.zip(h.values.sort).to_h
#  {:a=>1, :b=>2, :c=>5}

这只是对值进行排序,而不是对键进行排序。由于您的原始示例具有预先排序的键,因此从问题中不清楚是否希望在未排序的情况下对它们进行排序。

如果您想要对键和值进行排序并将它们链接在一起,则可以同时对键进行sort

hash.keys.sort.zip(h.values.sort).to_h
# {:a=>1, :b=>2, :c=>5}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接