有没有一种方法可以通过sort / sort_by更改哈希键?

时间:2019-12-10 00:13:13

标签: ruby

当前正在解决一个问题,该问题试图使我将前者转换为后者

{ 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}

如何在对值进行排序的同时更改哈希键?

4 个答案:

答案 0 :(得分: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 :(得分:1)

以下方法是什么?

{ a: 2, b: 5, c: 1 }.then { |hash| [hash.keys.sort, hash.values.sort].transpose }.to_h

答案 2 :(得分: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

答案 3 :(得分: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}