使用tiebreaker按长度排序数组

时间:2013-08-16 01:59:41

标签: ruby arrays sorting

我有Array Arraysort_by我希望按最长到最短排序。我用> a = [ [1, 2, 9], [4, 5, 6, 7], [1, 2, 3] ] > a.sort_by(&:length).reverse # or a.sort_by {|e| e.length}.reverse => [[4, 5, 6, 7], [1, 2, 3], [1, 2, 9]]

轻松地实现了这一点
[1, 2, 9]

然而,我想要的是对于相等长度的列表有一种打破平局。如果两个列表的长度相等,则最后一个条目更大的列表应该首先出现。因此,在上文中,应切换[1, 2, 3]和{{1}}。

我不关心两个列表具有相等长度和相等的最后一个元素的情况,如果发生这种情况,它们可以是任何顺序。我不知道是否/如何使用ruby内置排序来实现这一点。

3 个答案:

答案 0 :(得分:14)

您仍然可以使用sort_by执行此操作,您只需要意识到Ruby arrays compare element-by-element

  

ary< => other_ary→-1,0,+ 1或nil

     

[...]

     

比较每个数组中的每个对象(使用< =>运算符)。

     

阵列以“元素方式”进行比较;前两个不相等的元素将决定整个比较的返回值。

这意味着你可以使用数组作为sort_by键,然后输入一些整数否定来反转排序顺序,你得到:

a.sort_by { |e| [-e.length, -e.last] }

这将为您提供您正在寻找的[[4, 5, 6, 7], [1, 2, 9], [1, 2, 3]]

如果你没有使用数字,那么“否定反转命令”技巧将不起作用,那么使用Shaunak's sort方法。

答案 1 :(得分:3)

你去了:

a =  [ [1, 2, 9],[4, 5, 6, 7],[1, 2, 3] ]
a.sort { |a, b| (b.count <=> a.count) == 0 ? (b.last <=> a.last): (b.count <=> a.count)  } 

那应该给你:

[[4, 5, 6, 7], [1, 2, 9], [1, 2, 3]]

如何工作:我们将一个块传递给sort函数,该函数首先检查数组长度是否相同,如果不是,则继续检查最后一个元素。

答案 2 :(得分:2)

您可以使用

a.sort_by {|i| [i.length, i.last] }.reverse
# => [[4, 5, 6, 7], [1, 2, 9], [1, 2, 3]]