7
$\begingroup$

How can I sort all levels except the innermost level? The number of levels is unknown. For example:

list = {{{d, c}, {b, a}}, {{4, 3}, {2, 1}}}

If we needed to sort all levels, it would be easy to do expr /. List :> Composition[Sort, List], but that is not the case here.

I don't want to change the order of the innermost lists. For example, keep {d, c} as it is, not {c, d}, and similarly for other innermost lists. So the expected result in this case would be {{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}.

$\endgroup$
7
  • 1
    $\begingroup$ Can you give an example of the desired result, please? $\endgroup$ Commented Jul 9 at 15:46
  • $\begingroup$ What result do you expect? Flatten[list, 1] // Sort evaluates to {{2, 1}, {4, 3}, {b, a}, {d, c}} $\endgroup$ Commented Jul 9 at 15:46
  • 2
    $\begingroup$ Is the desired result {{{a, b}, {c, d}}, {{1, 2}, {3, 4}}}? Do I understand properly? $\endgroup$
    – bmf
    Commented Jul 9 at 15:48
  • $\begingroup$ @SjoerdSmit I don't want to change the order of innermost list for example keep {d, c} as it is, not {c,d}, and similarly for others in the innermost. So the expected result in this case would be {{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}. $\endgroup$
    – internet
    Commented Jul 9 at 16:06
  • 1
    $\begingroup$ Will Map[Sort, list, {0, Depth[list] - 3}]] do what you want? This evaluates to: {{{2, 1}, {4, 3}}, {{b, a}, {d, c}}} $\endgroup$ Commented Jul 9 at 19:06

2 Answers 2

4
$\begingroup$

Use Map[ f, expr, level spec]

l1 = {{{d, c}, {b, a}}, {{4, 3}, {2, 1}}};
l2 = {{{{h, g}, {f, e}}, {{8, 7}, {6, 5}}}, {{{d, c}, {b, a}}, {{4, 
      3}, {2, 1}}}};

Map[Sort, l1, {0, -3}]

(* {{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}*)

Map[Sort, l2, {0, -3}]

(*{{{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}, {{{6, 5}, {8, 7}}, {{f, e}, {h,
 g}}}}*)
$\endgroup$
2
  • $\begingroup$ I wanted to apply to abitrary list without knowing their structures in advance, however, I'll accept this. $\endgroup$
    – internet
    Commented Jul 11 at 11:10
  • $\begingroup$ Thank you for accepting my answer :-) I think my code will work on any list without knowing its structure, but if you have any problem, please let me know -- I'll improve my answer. $\endgroup$
    – A. Kato
    Commented Jul 12 at 4:16
5
$\begingroup$
l1 = {{{d, c}, {b, a}}, {{4, 3}, {2, 1}}};

l2 = {{{{d, c}, {b, a}}, {{4, 3}, {2, 1}}},
     {{{d, c}, {b, a}}, {{4, 3}, {2, 1}}}};

Using Replace, Fold and ArrayDepth as follows:

f = Replace[#, x_ :> Sort[x], {#2}] &;

Fold[f, #, {ArrayDepth[#] - 3, ArrayDepth[#] - 2}] &@l1

{{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}

Fold[f, #, {ArrayDepth[#] - 3, ArrayDepth[#] - 2}] &@l2

{{{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}, {{{2, 1}, {4, 3}}, {{b, a}, {d, c}}}}

$\endgroup$

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