Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have some list which looks like

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

and I need to group lists with equal sum of elements in ascending order like

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

and for

{{0, 0, 0, 0, 0}, {1, 1, 0, 0, 0}, {1, 1, 1, 1, 0}, {1, 1, 0, 1, 1}, {0, 1, 1, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}

I expected to see

{{{0, 0, 0, 0, 0}}, {{1, 1, 0, 0, 0}, {0, 1, 1, 0, 0}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}, {{1, 1, 1, 1, 0}, {1, 1, 0, 1, 1}, {0, 1, 1, 1, 1}}}
share|improve this question
2  
BTW, I've noticed something disconcerting about you posting history; you've gotten great answers on many questions, but have accepted none. You should go through you questions and accept the best adequate answer for each one (it is ok to wait a day or so to see if you get any better, but be certain not to forget or people will get frustrated with you after a while.) –  Pickett Oct 16 '13 at 15:48
    
Oh, sorry I didn't know. I'll do it tomorrow! –  Филипп Цветков Oct 16 '13 at 16:35
add comment

4 Answers

up vote 10 down vote accepted
Sort@GatherBy[{{0, 1}, {4}, {0, 0, 1}, {2, 0, 1}, {3, 0, 0}, {3, 1}, {0, 0, 0, 4}}, Total]

To make sure Sort always gets it right:

Sort[GatherBy[n, Total], Less[Total@First[#], Total@First[#2]] &]
share|improve this answer
    
n = {{0, 0, 0, 0, 0}, {1, 1, 0, 0, 0}, {1, 1, 1, 1, 0}, {1, 1, 0, 1, 1}, {0, 1, 1, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}; Sort@GatherBy[n, Total]; gives {{{0, 0, 0, 0, 0}}, {{1, 1, 1, 1, 0}, {1, 1, 0, 1, 1}, {0, 1, 1, 1, 1}}, {{1, 1, 0, 0, 0}, {0, 1, 1, 0, 0}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}} but I would like to get {{{0, 0, 0, 0, 0}}, {{1, 1, 0, 0, 0}, {0, 1, 1, 0, 0}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}, {{1, 1, 1, 1, 0}, {1, 1, 0, 1, 1}, {0, 1, 1, 1, 1}}} –  Филипп Цветков Oct 16 '13 at 13:53
    
Yes, it was only plain luck that the first version worked without having to use SortBy. But that's exactly why I added another version which, as I said, "always gets it right." (In the first version it works because the first number in each sublist is ascending in the way you would like to have it sorted. –  Pickett Oct 16 '13 at 15:10
    
So just to be clear, the topmost solution is only valid for the first example you provided. Not for subsequent examples. But I foresaw this, and provided the first version only as a curiosity to show that in this particular case it's this simple. –  Pickett Oct 16 '13 at 15:12
    
Your second line appears to be a SortBy[...,True]. This just defaults down to Sort again and makes it equal to your first solution. –  jVincent Oct 16 '13 at 15:43
    
@jVincent Yeah, silly me. I corrected it. I sure would have appreciated some downvotes/comments to alert me! With seven upvotes you tend to think you have it right! Ty! (+1 for yours, I like it better. It should get at least 14 upvotes.) –  Pickett Oct 16 '13 at 15:48
add comment

A simple approach is to just use:

GatherBy[SortBy[list,Total],Total]

This ensures that they appear in the correct order since they are gathered based on the appearance of the first element. In each sublist with the same total, they will be ordered based on OrderedQ, which puts them in order of number of elements afaik.

To verify that it works out:

 listA={{0,1},{4},{0,0,1},{2,0,1},{3,0,0},{3,1},{0,0,0,4}};
 listB={{0, 0, 0, 0, 0, 1}, {4}, {0, 0, 0, 0, 1}, {2, 0, 1}, {3, 0, 0}, {3, 1}, {0, 0, 0, 4}};

verify[v_] := Total[First[#]] & /@ v
verify@GatherBy[SortBy[listA, Total], Total]
verify@GatherBy[SortBy[listB, Total], Total]
(* {1,3,4} *)
(* {1,3,4} *)
share|improve this answer
add comment

I would write it like this:

list ~SortBy~ {Total} ~SplitBy~ Total

Note that putting the SortBy function inside a list (i.e. {Total} instead of just Total) means that SortBy will give a stable sort, so elements with the same total will stay in the order they were in the original list.

share|improve this answer
    
neat idea! Thanks for sharing/explaining –  Pinguin Dirk Oct 16 '13 at 16:33
add comment

Just for fun:

Pick[list, Total /@ list, #] & /@ Union[Total /@ list]

=> {{{0, 1}, {0, 0, 1}}, {{2, 0, 1}, {3, 0, 0}}, {{4}, {3, 1}, {0, 0, 0, 4}}}

where

list = {{0, 1}, {4}, {0, 0, 1}, {2, 0, 1}, {3, 0, 0}, {3, 1}, {0, 0, 
   0, 4}}

And

Pick[n, Total /@ n, #] & /@ 
  Union[Total /@ n] == {{{0, 0, 0, 0, 0}}, {{1, 1, 0, 0, 0}, {0, 1, 1,
     0, 0}, {0, 0, 1, 1, 0}, {0, 0, 0, 1, 1}}, {{1, 1, 1, 1, 0}, {1, 
    1, 0, 1, 1}, {0, 1, 1, 1, 1}}}

=> True

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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