按照数组中相同键的顺序对哈希键进行排序

5
我需要按照另一个数组中键的顺序对哈希进行排序:
hash = { a: 23, b: 12 }
array = [:b, :a]
required_hash #=> { b: 12, a: 23 } 

有没有一种方法可以用单行代码实现?

1
变量 ab 的值是什么? - sawa
3
@engineer,自Ruby v.1.9以来已经过去了几年,散列表键的插入顺序得到了维护。然而,散列表键被排序的想法仍然存在争议。个人而言,我已经广泛地利用了这种属性。 - Cary Swoveland
4个回答

8
hash = { a: 23, b: 12 }
array = [:b, :a]

array.zip(hash.values_at(*array)).to_h
  #=> {:b=>12, :a=>23}

步骤如下:
v = hash.values_at(*array)
  #=> [12, 23]
a = array.zip(v) 
  #=> [[:b, 12], [[:a, 23]]
a.to_h
  #=> {:b=>12, :a=>23}

我个人喜欢下面 @Ilya 的回答。 - Steve Wilhelm

6
你可以尝试类似这样的方法:
array = [:b, :a] 
{ a: 23, b: 12 }.sort_by { |k, _| array.index(k) }.to_h
#=> {:b=>12, :a=>23}

3
如果
hash = { a:23, b:12 }
array = [:b, :a]

作为一行代码:
Hash[array.map{|e| [e, hash[e]]}]

关于排序,这是一段时间以前的事情了,当时Ruby更改了实现方式,使得哈希键按照插入顺序排序。(在此之前,无法保证键会按照某种方式进行排序)。


好的回答,但我永远不会理解为什么人们会说“这是一行代码”,然后跟着一行代码。 - Cary Swoveland
1
@CarySwoveland,就个人而言,我这样做是为了强调Ruby的简洁性,相比C#/Java,你可以将许多东西写成一行代码。 - Candide
在C♯/Java中,换行符没有意义,无论多么复杂,你都可以将任何C♯/Java程序写成一行,这不是Ruby独有的特性。 - Jörg W Mittag

1

我没有看到任何排序,我认为你的做法基本上是这样的:

hash = { a:23, b:12 }
array = [:b, :a]
res = {}
array.each { |key| res[key] = hash[key] } && res # `&& res` is just syntax sugar to return result in single line
#=> {:b=>12, :a=>23}

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