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 '20 at 16:50
  • $\begingroup$ Are all of your lists of single digit elements? $\endgroup$
    – MikeY
    Mar 20 '20 at 18:25
  • $\begingroup$ If so, you can use lst[[Ordering@(ToString /@ lst)]] $\endgroup$
    – MikeY
    Mar 20 '20 at 18:33
  • 1
    $\begingroup$ Related: (26974) $\endgroup$
    – Mr.Wizard
    Mar 20 '20 at 20:01
  • $\begingroup$ Should be applicable to all numbers. Not necessarily single digits. $\endgroup$
    – liang
    Mar 21 '20 at 4:34
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 '20 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 '20 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 '20 at 11:04
  • $\begingroup$ @OkkesDulgerci ah shoot. PadRight it is :-) $\endgroup$ Mar 21 '20 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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