3

提供了以下红宝石哈希:

{
    cat: {
        1: 2,
        2: 10,
        3: 11,
        4: 1
    },
    wings: {
        1: 3,
        2: 5,
        3: 7,
        4: 7
    },
    grimace: {
        1: 4,
        2: 5,
        3: 5,
        4: 1
    },
    stubborn: {
        1: 5,
        2: 3,
        3: 7,
        4: 5
    }
}

如何通过“叶子”的总和(不包括“4”)对哈希进行排序,例如“猫”要比较的值是(2 + 10 + 11)= 23,“翅膀”的值是(3 + 5 + 7) = 15 所以如果我只比较这两个,它们的顺序是正确的,最高的总和在顶部。

可以安全地假设它总是 {1: value, 2: value, 3: value, 4: value} 因为这些是我定义的常量的键。

还可以安全地假设我只想排除键“4”,并始终使用键“1”、“2”和“3”

根据乔丹的建议,我得到了这个工作:

  tag_hash = tag_hash.sort_by do |h| 
    h[1].inject(0) do |sum, n| 
      n[0] == 4 ? sum : sum + (n[1] || 0)
    end
  end

结果似乎有点不对,但它似乎是我的代码,一旦我确认我会接受答案,谢谢乔丹!

我已经更新了我的解决方案以使用韦恩康拉德的想法,请参阅我对他的回答的评论 - 它是否可能在排序时没有携带所有内容,我在我的评论中链接到一个图像,以图表形式显示实际排序的结果..对我来说似乎很奇怪..

4

4 回答 4

8
tag_hash = tag_hash.sort_by do |_, leaf|
  leaf.reject do |key, _|
    key == 4
  end.collect(&:last).inject(:+)
end
于 2010-04-20T05:12:14.827 回答
2
my_hash.sort_by do |_, h|
  h.inject(0) do |sum, n|
    # only add to the sum if the key isn't '4'
    n[0] == 4 ? sum : (sum + n[1])
  end
end

当然,这可以缩短为一个难以理解的单行:

my_hash.sort_by {|k,h| h.inject(0) {|sum,n| n[0] == 4 ? sum : (sum + n[1]) } }
于 2010-04-20T02:32:47.410 回答
0

这个

puts a.sort_by { |k, v| -v.values[0..-1].inject(&:+) }

产生以下输出,这是你想要的吗?

cat
{1=>2, 2=>10, 3=>11, 4=>1}
wings
{1=>3, 2=>5, 3=>7, 4=>7}
stubborn
{1=>5, 2=>3, 3=>7, 4=>5}
grimace
{1=>4, 2=>5, 3=>5, 4=>1}
于 2010-04-20T06:48:53.323 回答
0

这似乎有效:

x.sort_by{ |_,h| h.values.take(3).inject(:+) }

这假设子哈希已排序(前三个条目是您要总结的条目)。

当您使用 ActiveSupport 时,您可以这样做:

x.sort_by{ |_,h| h.values.take(3).sum }

或者

x.sort_by{ |_,h| h.slice(1,2,3).values.sum }

Hash#slice 返回一个仅包含传递给 slice 的键的散列。Array#take 返回一个包含源数组的前 n 个条目的数组。

(我认为需要 Ruby 1.9.1)

于 2010-04-24T15:44:53.017 回答