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 a list of lists, and I'd like to build a new list, in which lists are in the same list if they have the same first and last element. Here's an example. Suppose I have

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

After some magic has happened, I would like to have

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

I was looking at Select and the others, but I can only come with ugly explicit loops that achieve this. I'm sure there's a nicer way of doing this. What could that be?

share|improve this question

3 Answers 3

up vote 7 down vote accepted

The following shall group the lists notwithstanding their order:

list = {{1, 2, 4}, {1, 3, 4}, {1, 2, 4, 5}, {1, 3, 4, 4}, {2, 4, 5}, {3, 4, 5}};
GatherBy[list, {First@#, Last@#} &]

(*
{{{1, 2, 4}, {1, 3, 4}, {1, 3, 4, 4}}, {{1, 2, 4, 5}}, {{2, 4, 5}}, {{3, 4, 5}}}
*)
share|improve this answer
list={{1, 2, 4}, {1, 3, 4}, {1, 2, 4, 5}, {1, 3, 4, 5}, {2, 4, 5}, {3, 4, 5}};

SplitBy[list, #[[{1, -1}]] &]
(* {{{1, 2, 4}, {1, 3, 4}}, {{1, 2, 4, 5}, {1, 3, 4, 5}}, {{2, 4, 5}}, {{3, 4, 5}}} *)
share|improve this answer
    
I think it isn't grouping the lists if they aren't contiguous –  belisarius Feb 18 '13 at 4:34
1  
Shouldn't that be GatherBy? –  Mr.Wizard Feb 18 '13 at 4:39
    
For some reason I interpreted the question as contiguous –  Rojo Feb 18 '13 at 4:46
    
Okay, fair enough. +1 –  Mr.Wizard Feb 18 '13 at 4:50
 list = {{1, 2, 4}, {1, 3, 4}, {1, 2, 4, 5}, {1, 3, 4, 4}, {2, 4, 5}, {3, 4, 5}};
 gthr[l_] :=  Cases[l, #] & /@ DeleteDuplicates[{#[[1]], ___, #[[-1]]} & /@ l] 
 gthr[list]
 (* { {{1,2,4},{1,3,4},{1,3,4,4}}, {{1,2,4,5}}, {{2,4,5}}, {{3,4,5}}} *)

Update: gthr decoded:

Form patterns from the first and last members of sublists in list:

 {#[[1]], ___, #[[-1]]}& /@ list   
 (* {{1, ___, 4}, {1, ___, 4}, {1, ___, 5}, {1, ___, 4}, {2, ___, 5}, {3, ___, 5}}*)

Remove duplicate elements from the list of patterns:

 DeleteDuplicates[%] 
 (* {{1, ___, 4}, {1, ___, 5}, {2, ___, 5}, {3, ___, 5}} *)

For each pattern get the elements in list matching that pattern:

 Cases[list,#]&/@%  
 (* { {{1,2,4},{1,3,4},{1,3,4,4}}, {{1,2,4,5}}, {{2,4,5}}, {{3,4,5}}} *)
share|improve this answer
1  
This is cool, but could you add a little explanation of what your code does for the benefit of less experienced future visitors? –  Verbeia Feb 18 '13 at 15:02

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.