I have a ragged list

ragged = {{a,b,c,d,e},{x,y,z}}


that I would like to trim (on the right) to be rectangular. The desired result is

{{a,b,c},{x,y,z}}


It seems like this should be a one-word operation but I can't find the one word. So far the best I can do is to PadRight with Null and then delete everything with a Null in it.

Transpose[
DeleteCases[
Transpose[
ragged,
Automatic,
Null
]
],
a_ /; MemberQ[a, Null]
]
]


This seems way too complicated for such a simple operation. What is the simplest way to do this?

You are looking for Take. To then make the array rectangular, I would do something like this

Take[ragged, All, Min[Length /@ ragged] ]

• How did he fix that without it showing the edit? Mar 20, 2012 at 15:30
• @BrettChampion I was within the 5 minute window. Mar 20, 2012 at 15:31

ragged[[All, 1 ;; Min[Length /@ ragged]]]


{{a, b, c}, {x, y, z}}

• Very nice ! You can even drop 1 and write ragged[[All, ;; Min[Length /@ ragged]]] Mar 20, 2012 at 15:41
• Yep! Good for the oneliner contest but potentially dangerous for sloppy readers (i.e. me). Mar 20, 2012 at 15:45

You could do something like

PadRight[ragged, {Automatic, Min[Length /@ ragged]}]

• Automatic apparently doesn't work on v7. Mar 20, 2012 at 15:31
• +1 for showing that PadRight can remove elements. I didn't know that. Mar 20, 2012 at 16:49

Here is a timing comparison of the methods presented. I had to modify Heike's code because it did not work on version 7.

SetAttributes[timeAvg, HoldFirst]

timeAvg[func_] :=
Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}]

ragged = RandomReal[99, #] & /@ RandomInteger[{25, 100}, 5000];

PadRight[ragged, {Length@ragged, Min[Length /@ ragged]}]; // timeAvg

ragged[[All, ;; Min[Length /@ ragged]]]; // timeAvg

Take[ragged, All, Min[Length /@ ragged]]; // timeAvg

0.02808

0.002864

0.002744

ragged = RandomReal[99, #] & /@ RandomInteger[{2500, 5000}, 50];

PadRight[ragged, {Length@ragged, Min[Length /@ ragged]}]; // timeAvg

ragged[[All, ;; Min[Length /@ ragged]]]; // timeAvg

Take[ragged, All, Min[Length /@ ragged]]; // timeAvg

0.01688

0.00009184

0.000088896


rcollyer wins!

• I modified my answer to what you proposed when I was fixed the "Trim" issue. Mar 20, 2012 at 15:43
• Darn. You win again, Mr. Wizard (or rcollyer, I a afraid of a grandfather paradox). Mar 20, 2012 at 15:49
• @rcollyer corrected Mar 20, 2012 at 15:49
• @YvesKlett well, we've already established that I'm part of the Mr.Wizard collective. Mar 20, 2012 at 15:58
• Great. Now I´ll have to spend the rest of the day to search for some far-fetched example to demonstrate Parts superiority. S´ not like I have a job or something. No borg, me! Mar 20, 2012 at 15:59

In version 10 the package GeneralUtilites contains the functions TrimLeft and TrimRight:

x = {{1, 2, 3}, {1, 2, 3, 4}, {1, 2}};

Needs["GeneralUtilities"]

TrimLeft[x]
TrimRight[x]

{{2, 3}, {3, 4}, {1, 2}}

{{1, 2}, {1, 2}, {1, 2}}


Burdened with the additional argument testing overhead of a packaged function these are not quite as fast as the raw methods posted earlier but they are sufficient. The core of each is akin to Yves Klett's answer:

lists[[All, -Min[Length /@ lists] ;; All]]

lists[[All, 1 ;; Min[Length /@ lists]]]
`