# Filter list with different list in it

I have a list like:

   {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1},
{{4, 18}, 1}, {{4, 14}, 3},  {4,15},      {{4, 16}, 2},{4,18}}


Now I want to filter this list. First I want to delete lists that have the form: {a,b} like {4,15} and {4,18}. So what remains is:

 {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1},
{{4, 18}, 1}, {{4, 14} ,3}, {{4, 16}, 2}}


And now I want only the lists which are a minimum: For example now you have a list with:

{{4, 14}, 1} and {{4, 14}, 3}
{{4, 16}, 1} and {{4, 16}, 2}


I want that only {{4, 14}, 1} and {{4, 16}, 1} remain (minimum of the third number).

Finally remains:

{{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}


How can I easily do this??

-
Glenn, as you can see from the answers below there is ambiguity in your question. Do you want to return only elements of the form {{_, _}, min} where min is the global minimum across all lists, or rather elements where min is the smallest value within the set that share a common first part (e.g. {4, 14})? – Mr.Wizard Dec 16 '12 at 23:08

## 6 Answers

Yet another way using Select and GatherBy:

list = {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17},
1}, {{4, 18}, 1}, {{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}};
x1 = Select[list, Length[#[[1]]] == 2 &];
x2 = GatherBy[x1, First];
(Sort[#] & /@ x2)[[All, 1]]


{{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}}

-
You could use SortBy[#,Last] instead of Sort[#, #1[[2]] < #2[[2]] &] . Or, for this problem, just Sort since the first elements are all the same – Simon Woods Dec 16 '12 at 17:31
@SimonWoods You're right, updated. – VLC Dec 16 '12 at 17:58

another way

list = DeleteCases[list, {x_Integer, y_Integer}];
min = Min[list[[All, 2]]];
Extract[list, Position[list[[All, 2]], min] ]


-
You're assuming the minimum (third number) is just going to be one number, in this case 1, but it seems the different lists could have various minimum numbers. – Chris Degnen Dec 16 '12 at 16:38
+1 for an alternate interpretation – Mr.Wizard Dec 16 '12 at 23:02
lst = {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1},
{{4, 17}, 1}, {{4, 18}, 1}, {{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}}

First /@ Sort /@ GatherBy[Cases[lst, {_List, _}], First]

{{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}}


Or with ~infix~:

First /@ Sort /@ lst ~Cases~ {_List, _} ~GatherBy~ First

-

Here's a fairly simple way of doing it:-

x = {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1},
{{4, 18}, 1}, {{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}};
x2 = Replace[x, {a_Integer, b_Integer} -> Null, {1}];
x3 = DeleteCases[x2, Null];
types = Union[x3[[All, 1]]];
First[Sort[Cases[x3, {#, _}]]] & /@ types


{{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}}

-

An approach based on Cases:

lst = {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1},
{{4, 17}, 1}, {{4, 18}, 1}, {{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}}

Cases[list, {{_, _}, Min[list /. {{_, _}, x_} -> x]}]


{{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}}

-

With

x = {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1},
{{4, 18}, 1}, {{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}};
x2 = {{{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1},
{{4, 14}, 3}, {4, 15}, {{4, 16}, 2}, {4, 18}, {{4, 14}, 2}};


you can also use

 Union[Cases[x, {{ _, _ }, _}], SameTest -> (First@#1 == First@#2 &)]


or

 (* if the elements {{a,b}, c} are already sorted with respect to the the last entry:*)
DeleteDuplicates[Cases[x, {{_, _}, _}], (#1[[1]] == #2[[1]] &)]
(* if not: *)
DeleteDuplicates[SortBy[#, Last] &@Cases[x, {{_, _}, _}], (#1[[1]] == #2[[1]] &)]


to get:

(* {{{4, 14}, 1}, {{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}} *)


Update: Further alternatives that preserve the ordering of the input list:

cleanUp2[x_] :=  With[{gthrd = GatherBy[Select[x, Depth[#] == 3 &], First]},
Join @@ Pick[#, Last /@ #, Min @@ (Last /@ #)] & /@ gthrd];
cleanUp3[x_] := DeleteCases[x, Alternatives[{_Integer, _},
{w : {_, _}, z_} /; z > Min @@ Last /@ Cases[x, {w, _}]]];
cleanUp4[x_] :=  Cases[x, {w : {_, _}, z_} /; z == Min @@ Last /@ Cases[x, {w, _}]];


Example:

 cleanUp3[x2]
(* {{{4, 15}, 1}, {{4, 16}, 1}, {{4, 17}, 1}, {{4, 18}, 1}, {{4, 14}, 2}} *)

-