In order to descend-sort an array a
of strings, reverse
can be used.
a.sort.reverse
But when you want to use a string among multiple sort keys, that cannot be done. Suppose items
is an array of items that have attributes attr1
(String
), attr2
(String
), attr3
(Integer
). Sort can be done like:
items.sort_by{|item| [item.attr1, item.attr2, item.attr3]}
Switching from ascending to descending can be done independently for Integer
by multiplying it with -1
:
items.sort_by{|item| [item.attr1, item.attr2, -item.attr3]}
But such method is not straightforward for String
. Can such method be defined? When you want to do descending sort with respect to attr2
, it should be written like:
items.sort_by{|item| [item.attr1, item.attr2.some_method, item.attr3]}
I think you can always convert your strings into an array of integers (ord
). Like this:
strings = [["Hello", "world"], ["Hello", "kitty"], ["Hello", "darling"]]
strings.sort_by do |s1, s2|
[
s1,
s2.chars.map(&:ord).map{ |n| -n }
]
end
PS:
As @CarySwoveland caught here is a corner case with empty string, which could be solved with this non elegant solution:
strings.sort_by do |s1, s2|
[
s1,
s2.chars.
map(&:ord).
tap{|chars| chars << -Float::INFINITY if chars.empty? }.
map{ |n| -n }
]
end
And @Jordan kindly mentioned that sort_by uses Schwartzian Transform so you don't need preprocessing at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With