# Given a list of lists, build a list in which lists with equal first and last elements are grouped together

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?

-

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}}}
*)

-
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}}} *)

-
I think it isn't grouping the lists if they aren't contiguous – Dr. belisarius Feb 18 '13 at 4:34
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}}} *)

-
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