在Ruby中,有一种简短而又甜蜜的方法可以按分数降序对数组的哈希值进行排序:
scored = {:id=>[1, 2, 3], :score=>[8.3, 5, 10]}
所以它看起来像这样?:
scored = {:id=>[3, 1, 2], :score=>[10, 8.3, 5]}
我找不到一个例子,我可以像这样在哈希中对数组进行排序?我可以用一些令人讨厌的代码做到这一点,但我觉得应该有1或2个衬垫来做它吗?
答案 0 :(得分:3)
您可以使用sort_by
scored = {:id=>[1, 2, 3], :score=>[8.3, 5, 10]}
scored.tap do |s|
s[:id] = s[:id].sort_by.with_index{ |a, i| -s[:score][i] }
s[:score] = s[:score].sort_by{ |a| -a }
end
#=> {:id=>[3, 1, 2], :score=>[10, 8.3, 5]}
答案 1 :(得分:2)
order = scored[:score].each_with_index.sort_by(&:first).map(&:last).reverse
#=> [2,0,1]
scored.update(scored) { |_,a| a.values_at *order }
#=> {:id=>[3, 1, 2], :score=>[10, 8.3, 5]}
如果scored
不要变异,请将update
替换为merge
。
有些观点:
order
使读者更容易理解正在发生的事情。<=>
的类。)arr
的方法是使用Enumerable#max_by:arr.max_by(arr.size).to_a
。第一行可以替换为:
arr = scored[:score]
order = arr.each_index.sort_by { |i| arr[i] }.reverse
#=> [2,0,1]
答案 2 :(得分:1)
这是一种可能的解决方案。它有一个中间步骤,它使用scores
对象的压缩版本,但产生正确的输出:
s = scored.values.inject(&:zip).sort_by(&:last).reverse
#=> [[3, 10], [1, 8.3], [2, 5]]
result = { id: s.map(&:first), score: s.map(&:last) }
#=> { :id => [3, 1, 2], :score => [10, 8.3, 5] }