8
$\begingroup$

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.

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

4 Answers 4

5
$\begingroup$

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

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

lsts[[Ordering @ PadRight @ lsts]]
{{1, 2, 8}, {1, 6}, {2}}

Related examples:

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

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

$\endgroup$
4
$\begingroup$

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}} *)
$\endgroup$
2
$\begingroup$
NumericalSort[{{1, 6}, {1, 2, 8}, {2}}]
$\endgroup$
2
  • 1
    $\begingroup$ It first considers the length of sub list. Try NumericalSort[{{1, 6, 9, 8}, {1, 2, 8}, {2}}] $\endgroup$ Mar 21, 2020 at 11:04
  • $\begingroup$ @OkkesDulgerci ah shoot. PadRight it is :-) $\endgroup$ Mar 21, 2020 at 12:19

Your Answer

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

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