在 ruby​​ 中对嵌套哈希进行排序

发布于 2024-08-29 03:55:25 字数 934 浏览 7 评论 0原文

提供以下 ruby​​ 哈希:

{
    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”)对哈希进行排序,例如“cat”的比较值将是(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

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

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

Provided the following ruby hash:

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

How can I sort the hash by the sum of 'leaf' excluding "4", for instance the value to compare for "cat" would be (2 + 10 + 11) = 23, the value for "wings" would be (3 + 5 + 7) = 15 so if I was comparing just those two they would be in the correct order, highest sum on top.

It is safe to assume that it will ALWAYS be {1: value, 2: value, 3: value, 4: value} as those are keys for constants I have defined.

It is also safe to assume that I will only ever want to exclude the key "4", and always use the keys "1", "2", and "3"

Based on Jordan's suggestion I got this to work:

  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

The results seem a bit off but it appears to be my code, once I confirm that I'll accept the answer, thanks Jordan!

I've updated my solution to use Wayne Conrad's idea, see my comment on his answer - Is it possible that its not carrying everything when it sorts, I linked to an image in my comment that shows the result of the actual sort in graph form.. seems odd to me..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笛声青案梦长安 2024-09-05 03:55:25
tag_hash = tag_hash.sort_by do |_, leaf|
  leaf.reject do |key, _|
    key == 4
  end.collect(&:last).inject(:+)
end
tag_hash = tag_hash.sort_by do |_, leaf|
  leaf.reject do |key, _|
    key == 4
  end.collect(&:last).inject(:+)
end
云巢 2024-09-05 03:55:25
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]) } }
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

This can, of course, be shortened to a hideously unreadable one-liner:

my_hash.sort_by {|k,h| h.inject(0) {|sum,n| n[0] == 4 ? sum : (sum + n[1]) } }
溺渁∝ 2024-09-05 03:55:25

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}

This

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

produces the following output, was this what you wanted?

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}
心如狂蝶 2024-09-05 03:55:25

这似乎有效:

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 返回仅包含传递给切片的键的哈希值。 Array#take 返回一个包含源数组的前 n 个条目的数组。

(我认为需要 Ruby 1.9.1)

This seems to work:

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

This assumes that the subhashes are sorted (the first three entries are the entries you want to sum up).

When you use ActiveSupport you could do this:

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

or

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

Hash#slice returns a hash that contains only the keys passed to slice. Array#take returns an array containing the first n entries of the source array.

(Ruby 1.9.1 required i think)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文