# SortBy first element then second element, and so on?

SortBy can sort list by first element easily like so:

SortBy[{{1, 6}, {1, 2, 8}, {2}}, First]


and the result is:

{{1, 6}, {1, 2, 8}, {2}}

How do you apply a sort of dictionary order, so that it compare the first element, then second element, and so on (if available). So the above result could become:

{{1, 2, 8}, {1, 6}, {2}}

Because of 2 and 6.

• Maybe you can use this function (sorts lists lexicographically) mathematica.stackexchange.com/questions/85606/… Mar 20, 2020 at 16:50
• Are all of your lists of single digit elements? Mar 20, 2020 at 18:25
• If so, you can use lst[[Ordering@(ToString /@ lst)]] Mar 20, 2020 at 18:33
• Related: (26974) Mar 20, 2020 at 20:01
• Should be applicable to all numbers. Not necessarily single digits. Mar 21, 2020 at 4:34

Like Pillsy I thought to pad the list. In the case given a simpler form works:

lsts = {{1, 6}, {1, 2, 8}, {2}};


{{1, 2, 8}, {1, 6}, {2}}


Related examples:

• interesting, why lsts is followed by "[[" instead of single "["? Usually function is called by single "[". Is this a different syntax? Mar 21, 2020 at 4:45
• found it in this document reference.wolfram.com/language/howto/GetElementsOfLists.html. That it's a short form of Part function. Mar 21, 2020 at 7:30

If your list contains only positive elements, then this may work.

SeedRandom@1
n = 100;
list = TakeList[RandomInteger[{1, 10}, n], RandomInteger[{1, 7}, 10]]


{{2, 5, 1}, {8, 1, 1, 9, 7}, {1, 5, 2, 9, 6}, {2, 2, 2, 4, 3, 2, 7}, {1, 3, 7, 5, 6, 5, 4}, {1}, {2, 4, 6, 4, 1}, {4, 3}, {4, 10, 6}, {2}}

max = Length /@ list // Max;
Sort[PadRight[#, max] & /@ list] // DeleteCases[#, 0, Infinity] &


{{1}, {1, 3, 7, 5, 6, 5, 4}, {1, 5, 2, 9, 6}, {2}, {2, 2, 2, 4, 3, 2, 7}, {2, 4, 6, 4, 1}, {2, 5, 1}, {4, 3}, {4, 10, 6}, {8, 1, 1, 9, 7}}

Edit:

SeedRandom@1
n = 100;
list = TakeList[RandomInteger[10, n], RandomInteger[{1, 10}, 10]]


{{1, 4, 0, 7, 0}, {0, 8, 6, 0, 4, 1, 8, 5}, {1}, {1, 1, 3, 2, 10, 1, 6, 0}, {2, 6, 4, 5, 4, 3, 0, 1}, {3, 5, 3, 0}, {3, 2, 3, 9, 5, 1}, {5, 2, 3, 9, 1, 0}, {4}, {4, 1, 5, 2, 7, 9}}

 smallNumber = -100;
max = Length /@ list // Max;
Sort[PadRight[#, max, smallNumber] & /@ list] // DeleteCases[#, smallNumber, Infinity] &


{{0, 8, 6, 0, 4, 1, 8, 5}, {1}, {1, 1, 3, 2, 10, 1, 6, 0}, {1, 4, 0, 7, 0}, {2, 6, 4, 5, 4, 3, 0, 1}, {3, 2, 3, 9, 5, 1}, {3, 5, 3, 0}, {4}, {4, 1, 5, 2, 7, 9}, {5, 2, 3, 9, 1, 0}}

If you pad out the lists on the left with $$-\infty$$, you ensure that a short list which is a prefix of a long list will come before it, giving you a lexicographic sort. Then you can use Ordering and Part to pull out the old elements.

data = {{1, 6}, {1, 2, 8}, {2}}
With[{n = Max[Length /@ data]},
Part[data, Ordering[PadRight[#, n, -Infinity] & /@ data]]]

(* {{1, 2, 8}, {1, 6}, {2}} *)

NumericalSort[{{1, 6}, {1, 2, 8}, {2}}]

• It first considers the length of sub list. Try NumericalSort[{{1, 6, 9, 8}, {1, 2, 8}, {2}}] Mar 21, 2020 at 11:04
• @OkkesDulgerci ah shoot. PadRight it is :-) Mar 21, 2020 at 12:19