按第二个值对二维数组进行排序

26

好的,假设我有一个数组,如下所示[[z,1],[d,3],[e,2]],如何按每个包含数组的第二个元素对该数组进行排序? 这样我的数组将看起来像以下内容? [[z,1],[e,2],[d,3]]?


2
请注意,这实际上是一个数组的数组,而不是一个二维数组。 - Phrogz
2个回答

46
arr = [[:z,1], [:d,3], [:e,2]]
arr.sort {|a,b| a[1] <=> b[1]}
# => [[:z, 1], [:e, 2], [:d, 3]]

正如用户@Phrogz指出的那样,如果内部数组恰好每个有两个元素:

arr.sort_by{|x,y|y} # => [[:z, 1], [:e, 2], [:d, 3]]
arr.sort_by(&:last) # => [[:z, 1], [:e, 2], [:d, 3]]

14
更简单的写法是:arr.sort_by{|s,n| n},或者在 Ruby 1.9 中可以使用arr.sort_by(&:last)。请注意,这里不会提供解释性内容。 - Phrogz
@Phrogz 更喜欢使用sort,因为在Ruby 2.4中(实际上从2.0开始或甚至更早),sort_by不存在,只有sort_by!。而且文档中说: 结果不能保证稳定。当两个键相等时,相应元素的顺序是不可预测的。 因此,要使用sort_by!,必须具有唯一的键。 所以@maerics请编辑您的帖子以说明这一点,或删除sort_by - noraj
请注意,至少从v1.8.7开始数组是Enumerable#sort_by(http://ruby-doc.org/core-1.8.7/Enumerable.html#method-i-sort_by),且问题中未要求稳定性。 - maerics
按第二列排序,然后任何平局都将按第一列排序呢? - kraftydevil

2

根据用户maerics的回答,可以提供升序排列。这个答案对我非常有用,谢谢。 对于降序排序,我使用 -

arr = [[:z,1], [:d,3], [:e,2]]
arr.sort {|a,b| a[1] <=> b[1]}.reverse
#=> [[:d, 3], [:e, 2], [:z, 1]]

1
你可以通过简单地执行 arr.sort{|a,b|| b[1] <=> a[1]}(注意比较运算符操作数的反向顺序)来保存“reverse”调用。 - maerics
1
你的代码中有一个错别字,正确的代码是 arr.sort{|a,b| b[1] <=> a[1]}。你多输入了一个管道符号。 - Fred

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