
Re: split the sublists into parts according to some rules
Posted:
Sep 4, 2012 5:46 AM


On Sep 3, 12:01 am, Ray Koopman <koop...@sfu.ca> wrote: > On Aug 31, 1:01 am, Joug Raw <joug...@gmail.com> wrote: >> Dear all, >> >> I have a long list which has many sublists inside, >> >> Thelonglist={{a,b,c,d,e},{x,y,z},{a1,a2,a3,a4},...} >> >> Each sublist has length > 1(no single element sublist exists). And the >> lengths of the sublists are different and unknow in advanced. The length >> of some of the sublists are odd number, such as {a,b,c,d,e} and {x,y,z}. >> Some sublists have even number list length, like {a1,a2,a3,a4}. >> >> What I want to achieved is to split each sublist into two (or three, or >> more) parts. In the two parts case, if the length of original sublist is >> even number, the two new parts will have same length, e.g, {a1,a2,a3,a4} >> become {{a1,a2},{a3,a4}}. If the sublist has length in odd number, >> after splitting one of the two parts should have one more element than >> the other. >> >> That is, >> Input: Thelonglist={{a,b,c,d,e}, {x,y,z}, {a1,a2,a3,a4},...} >> Output: Newlist={{a,b,c}, {d,e}}, {{x,y}, {z}}, {{a1,a2}, {a3,a4}},...} >> >> Or the same idea for the three parts case, >> Input: Thelonglist={{a,b,c,d,e}, {x,y,z}, {a1,a2,a3,a4},...} >> Output: Newlist={{{a,b}, {c,d}, {e}}, {{x},{y},{z}}, {{a1}, {a2}, >> {a3,a4}}, ...} >> >> For the case of 4 parts, the number 4 is larger than the length of some >> sublists and I will abandon those list with short length. >> Input: Thelonglist={{a,b,c,d,e}, {x,y,z}, {a1,a2,a3,a4},...} >> Output: Newlist={{{a}, {b}, {c}, {d,e}}, {{a1}, {a2}, {a3}, {a4}}, ...} >> >> Could there be a simple function to achieve this idea generally? Say, a >> function like *SplittoPart[**list_*, *partnumber_**]*, in which I just need >> to give the input list and the number of parts of sublists I want to have. >> Then it will do the job above. If the number of sublist is larger then the >> length of some sublists, the function just abandon those short list and do >> the split(or partition) work on the other lists with long enough length. >> Could some one help me on this? >> >> If that is too complicated, I would still be happy to see some one could >> give me a solution only for the case of splitting to two parts, >> >> Input: Thelonglist={{a,b,c,d,e}, {x,y,z}, {a1,a2,a3,a4},...} >> Output: Newlist={{a,b,c}, {d,e}}, {{x,y}, {z}}, {{a1,a2}, {a3,a4}},...} >> >> Thanks a lot for your kind help! > > splitr[list_,r_] := subsplitr[#,r]&/@list/.{}>Sequence[] > > subsplitr[sublist_,r_] := With[{n = Length@sublist}, If[n < r, {}, > Take[sublist,#]& /@ (Transpose@{Most@#+1,Rest@#}&)[ > FoldList[Plus,0,Floor[n/r]+Boole@Thread[Range@r<=Mod[n,r]]]]]] > > longlist = {{a, b, c, d, e}, {x, y, z}, {a1, a2, a3, a4}}; > > splitr[longlist,2] > > {{{a, b, c}, {d, e}}, {{x, y}, {z}}, {{a1, a2}, {a3, a4}}} > > splitr[longlist,3] > > {{{a, b}, {c, d}, {e}}, {{x}, {y}, {z}}, {{a1, a2}, {a3}, {a4}}} > > splitr[longlist,4] > > {{{a, b}, {c}, {d}, {e}}, {{a1}, {a2}, {a3}, {a4}}}
Here are two alternate versions of the sublist splitter:
subsplitr2[sublist_,r_] := With[{n = Length@sublist}, If[n < r, {}, Take[sublist,#]& /@ Transpose@{Most@#+1,Rest@#}& @ FoldList[Plus,0,Floor[n/r] + UnitStep[Mod[n,r]Range@r]]]]
subsplitr3[sublist_,r_] := With[{n = Length@sublist}, If[n < r, {}, Take[sublist,#]& /@ Transpose@{Prepend[Most@#+1,1],#}&[ Floor[n/r]*Range@r + Clip[Range@r,{1,Mod[n,r]}]]]]

