我目前正在使用以下代码对 Ruby 中的数组(数字(数组进行排序:
grapes_sorted = vintages_grapes.group_by(&:itself).sort_by do |k, v| -v.size end.map(&:first)
效果很好。 但是,我想将与每种排序对应的计数器存储在另一个数组中。
我试过了:
grapes_sorted_counters = []
grapes_sorted = vintages_grapes.group_by(&:itself).sort_by do |k, v|
-v.size
grapes_sorted_counters << v.size
end.map(&:first)
它存储计数器,但是,排序已损坏,而不是按应有的顺序排序。我想 v.size(而不是 -v.size(是块中问题的原因。
如何在 grapes_sorted_counters[] 中正确存储出现次数? 谢谢。
我相信你的代码的问题已经确定,所以我会建议一种替代方法。
grapes = %w|red blue red green yellow red blue blue green red|
#> ["red", "blue", "red", "green", "yellow", "red", "blue",
# "blue", "green", "red"]
grapes.tally.sort_by { |_,count| -count }.map(&:first)
#=> ["red", "blue", "green", "yellow"]
请参阅枚举#计数。
步骤如下。
h = grapes.tally
#=> {"red"=>4, "blue"=>3, "green"=>2, "yellow"=>1}
a = h.sort_by { |_,count| -count }
#=> [["red", 4], ["blue", 3], ["green", 2], ["yellow", 1]]
a.map(&:first)
#=> ["red", "blue", "green", "yellow"]
是这部分把你搞砸了:
sort_by do |k, v|
-v.size
grapes_sorted_counters << v.size
end
您正在尝试按-v.size
排序。但是块的返回值是grapes_sorted_counters << v.size
。
因此,只需切换这些行的顺序即可。
我认为无论如何您的排序中都有一个错误。
我目前正在使用以下代码对 Ruby 中的数组(数字(数组进行排序:
我假设输入值是这样的
vintages_grapes = [[3,2], [3,2,1], [3]]
因此,在第一步中,您执行group_by
vintages_grapes.group_by(&:itself)
# -> {[3, 2]=>[[3, 2]], [3, 2, 1]=>[[3, 2, 1]], [3]=>[[3]]}
您可以看到这些值都嵌套在另一个数组[]
中(它们的大小均为 1(。
sort_by do |key, value|
-value.size # size 1 for all values
end
group_by不应该是必需的,你可以做
result = []
vintages_grapes.sort_by do |array|
result << array.size
result.sort!
-array.size
end
我很好奇你认为
-v.size
在做什么。 – 铁皮人 39分钟前
它首先按最大值对计数器进行排序。
这不是sort
或sort_by
的工作方式。两者都依赖于块返回的值来指示如何对值进行排序。
此示例更像您的代码,您尝试否定size
的值,但随后返回数组。这将导致升序排序:
foo = [1, 3, 2, 4]
foo.sort_by { |i|
-i
i
}
# => [1, 2, 3, 4]
如果将否定值返回到块,则结果使用降序:
foo.sort_by { |i|
i
-i
}
# => [4, 3, 2, 1]
您的代码正在执行以下操作:
bar = []
foo.sort_by { |i|
-i
bar << i
}
# => [1, 3, 2, 4]
这导致bar
具有原始订单,因为它以与它们在foo
中存在的顺序相同的顺序填充,然后将其传递给map
。而且,在排序块内分配将始终这样做。您希望在该块关闭并且 Ruby 返回有序值后执行此操作。
综上所述,sort_by
使用错误的方法,您应该改用sort
。为什么在 Ruby 的sort_by
文档中进行了解释,因此请查看那里以获取更多信息。
此外,最好使用reverse
方法反转顺序,而不是通过否定值来完成。请参阅"如何在 Ruby 中按降序对数组进行排序"。