Sort an array of arrays by length with a tie-breaker

I have an Array of Array , which I want to sort by length to the shortest. I achieved this quite easily with sort_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]] 

I want, however, to have a kind of tie-break for lists of the same length. If the length of the two lists is the same, the list whose last record is longer should be the first. Thus, in the above case, you should switch [1, 2, 9] and [1, 2, 3] .

I don't care when two lists have equal length and equal last element, they can be in any order if that happens. I don't know how and how I can achieve this with ruby's built-in sort.

+6
source share
3 answers

You can still do this with sort_by , you just need to understand that Ruby Matrices are compared by elements :

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

[...]

Each object in each array is compared (using the <=> operator).

Arrays are compared on a per-element basis; the first two elements that are not equal will determine the return value for the entire comparison.

This means that you can use arrays as the sort_by key and then sort_by integer negation bit to reverse the sort order, and you will get:

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

This will give you the [[4, 5, 6, 7], [1, 2, 9], [1, 2, 3]] you are looking for.

If you are not using numbers, so the “negate to reverse order” trick will not work, use the Shaunak sort approach.

+13
source

There you go:

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

This should give you:

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

How it works: we pass a function for sorting, which first checks to see if the length of the array is the same if it does not continue to check the last element.

+3
source

you can use

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

Source: https://habr.com/ru/post/951853/


All Articles