3
$\begingroup$

Mathematica can sort {"b","d","a","c"} into {"a","b","c","d"} with a simple application of Sort. What ordering function/command is being used?

It isn't <: "a" < "b" doesn't return True or False, just a < b.

I'm trying to sort a large data set that contains both strings and numeric values. An example:

data = {{9, 8, "b"}, {4, 2, "d"}, {0, 3, "a"}, {4, 9, "c"}}.

I can sort by the second element of each set:

Sort[data, #2[[2]] > #1[[2]] &] returns

{{4, 2, "d"}, {0, 3, "a"}, {9, 8, "b"}, {4, 9, "c"}}.

But Sorting by the third element doesn't work:

Sort[data, #2[[3]] > #1[[3]] &] returns data unchanged:

{{9, 8, "b"}, {4, 2, "d"}, {0, 3, "a"}, {4, 9, "c"}}.

It feels like a hack, but I can sort using Ordering and OrderedQ:

data[[Ordering[data[[All, 3]]]]] returns

{{0, 3, "a"}, {9, 8, "b"}, {4, 9, "c"}, {4, 2, "d"}}, as does

Sort[data, OrderedQ[{#1[[3]], #2[[3]]}] &].

Neither feels natural. Is there a lexicographical/alphabetical "inequality" command, or is it just OrderedQ?

$\endgroup$

2 Answers 2

6
$\begingroup$

You can use AlphabeticOrder:

data = {{9, 8, "b"}, {4, 2, "d"}, {0, 3, "a"}, {4, 9, "c"}};

Sort[
    data, 
    AlphabeticOrder[ #1[[3]], #2[[3]] ]&
]

{{0, 3, "a"}, {9, 8, "b"}, {4, 9, "c"}, {4, 2, "d"}}

$\endgroup$
1
  • $\begingroup$ That's it. I didn't seem to be using the right search terms online to find that command. $\endgroup$
    – GregH
    Oct 26, 2018 at 12:15
5
$\begingroup$

AlphabeticOrder does not exist in version 10.1 which I use, but I don't believe it is necessary here. I argue that Order and OrderedQ are the more canonical (and certainly general) functions.

Additionally, where possible you should make use of SortBy (e.g. SortBy[data, #[[3]] &]) or Ordering (as you already did) rather than Sort, as these are more efficient methods.

An alternative to OrderedQ if you have need of Sort itself:

Sort[data, 0 < Order[#[[3]], #2[[3]]] &]
Sort[data, 0 > Order[#[[3]], #2[[3]]] &]
{{0, 3, "a"}, {9, 8, "b"}, {4, 9, "c"}, {4, 2, "d"}}
{{4, 2, "d"}, {4, 9, "c"}, {9, 8, "b"}, {0, 3, "a"}}

This is actually more concise than AlphabeticOrder.

$\endgroup$
2
  • 3
    $\begingroup$ In law they say "lex specialis derogat legi generali": Sometimes the more special function has its merits and is maybe is less abstract? AlphabeticOrder on the other hand is more general than Order because English is not the only language out there... ;-) $\endgroup$
    – gwr
    Oct 26, 2018 at 14:23
  • $\begingroup$ @gwr I didn't notice that AlphabeticOrder handled different languages; that's nice! I have already voted for your answer. And thanks for the Latin lesson. $\endgroup$
    – Mr.Wizard
    Oct 26, 2018 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.