How to sort strings descendantly in sort_by method?

Here’s the Example:

array = %w[ ABca DCbc CDde CBab CAce
BCee DCea AAda EEec CCeb
DAca BCec EBab EBeb ACbd
DAda DAdc DBae BAcb DEda ]

array.sort_by! {|str| [ str[2,2], str[0,2] ] }

sort the strings first by the last 2 letters, second by the first 2

letters

p array

=> [“CBab”, “EBab”, “DBae”, “DCbc”, “ACbd”, “ABca”, “DAca”, “BAcb”,

“CAce”, “AAda”, “DAda”, “DEda”, “DAdc”, “CDde”, “DCea”, “CCeb”, “EBeb”,
“BCec”, “EEec”, “BCee”]

However, if I want the strings to be sorted, second by the first 2
letters descendantly, which means: “aa” comes before “ee”, but “AA”
comes after “EE”, “CBab” should swap the position with “EBab”. How can I
do this easily, using sort_by method?

If the sorting thing is numeric, I can put a minus sign before it,
that’s a descendant sorting. But I don’t know how to do this with a
string.

Any easy way? Thank you!

How do you think strings are compared?

array = %w[
AAab ACab ABab
AAaa ACaa ABaa
]

sorted = array.sort_by do |str|
[str[2,2], -str[0].ord, -str[1].ord ]
end

p sorted

–output:–
[“ACaa”, “ABaa”, “AAaa”, “ACab”, “ABab”, “AAab”]

7stud – wrote in post #1008846:

How do you think strings are compared?

array = %w[
AAab ACab ABab
AAaa ACaa ABaa
]

sorted = array.sort_by do |str|
[str[2,2], -str[0].ord, -str[1].ord ]
end

Note that’s ruby for 1.9 only. For 1.8 you can write

[str[2,2], -str[0], -str[1]]

but that doesn’t work on 1.9.

For something which works on both:

sorted = array.sort { |a,b|
cmp = a[2,2] <=> b[2,2]
cmp != 0 ? cmp : b[0,2] <=> a[0,2]
}

7stud – wrote in post #1008853:

Joey Z. wrote:

How to sort strings descendantly in SORT_BY method?

Brian C. wrote in post #1008851:

For something which works on both:

sorted = array.SORT

Yes, I know the OP said “using sort_by method”.

But if you’re trying to fit a screw, a hammer isn’t necessarily the
right tool.

Joey Z. wrote:

How to sort strings descendantly in SORT_BY method?

Brian C. wrote in post #1008851:

For something which works on both:

sorted = array.SORT

Well, why I wanted a sort_by method was that I thought sort_by is
faster than sort. However, I just took a benchmark test to see the
difference between these two methods, and found that sort_by is slower
than sort!

I was wrong, I should take the relative verbose but effective sort
method.

Thank you both!

Joey Z. wrote in post #1008875:

Well, why I wanted a sort_by method was that I thought sort_by is
faster than sort.

It will be when the calculations you are doing to produce the sort
criteria are intensive enough. sort_by() turns every element into a two
element
array containing the element and its sort criteria. That way
the sort criteria is only calculated once for every element. Then a
master array
containing the sub arrays is sorted by the first element of the sub
arrays, i.e. the sort criteria. Finally, the sub arrays in the master
array are mapped to the second element of each subarray, i.e. the
original elements, producing the final sorted array of the original
elements.

On the other hand, sort() calculates the sort criteria anew every time
it compares two elements in the original array. Sometimes its faster to
do just that.