# How can one select elements from a list that are satisfied a criteria which need to compare with other elements in the list?

For example: I want to select elements from a list {1,4,3,2,5} that are bigger than its previous element. {4,5} satisfies the criteria: 4 is greater than 1 and 5 is greater than 2(Ignore the first element).

In general, Is there any simple way to select elements from a list that are satisfied a criteria which need to compare with other elements in the list?

• Something like First /@ Split[{1, 4, 3, 2, 5}, Greater] // Rest? Commented Dec 5, 2014 at 11:35

@belisarius comment is pure genius, but if you need more flexibility for your criteria take a look at v10's amazing MovingMap

list={1,4,3,2,5};

(* Find elements greater than the one before *)
Pick[Rest@list, MovingMap[#[[1]]<#[[2]]&,{1,4,3,2,5}, {2}]]
(* {4,5} *)

(* Find elements smaller than the next one *)
Pick[Most@list, MovingMap[#[[1]]<#[[2]]&,{1,4,3,2,5}, {2}]]
(* {1,2} *)

(* Find a valley *)
Pick[Rest@*Most@list, MovingMap[#[[1]]>#[[2]]<#[[3]]&,{1,4,3,2,5}, {3}]]
(* {2} *)

(* Find a peak *)
Pick[Rest@*Most@list, MovingMap[#[[1]]<#[[2]]>#[[3]]&,{1,4,3,2,5}, {3}]]
(* {4} *)


You just have to mind the edges. You can either use a sensible padding or create a function that handles the special cases!

• +1 Still on V9 here, but MovingMap[] looks great. Hope the performance isn't lame. Anyway, at the expense of memory it can be simulated on previous versions with f /@ Partition[list,n, 1] Commented Dec 5, 2014 at 13:05
• wow!Just updated my mathematica to V10, never seen MovingMap[] before,it's cool! Commented Dec 6, 2014 at 6:21
• Well, took me only six years to discover MovingMap[]. Commented Jun 13, 2020 at 6:38

I prefer small steps. So try this:

list1 = {1, 4, 3, 2, 5};

list2 = Partition[list1, 2, 1];

list3 = Select[list2, #[[2]] > #[[1]] &];


output is: {{1,4}, {2,5}}

list3[[All, 2]]


output is: {4, 5}

list = {1, 4, 3, 2, 5};


Using SequenceCases (new in 10.1)

Find elements greater than the one before

SequenceCases[list, {a_, b_} /; a < b :> b]


{4, 5}

Find elements smaller than the next one

SequenceCases[list, {a_, b_} /; a < b :> a]


{1, 2}

Find a valley

SequenceCases[list, {a_, b_, c_} /; a > b < c :> b]


{2}

Find a peak

SequenceCases[list, {a_, b_, c_} /; a < b > c :> b]


{4}

Because I like Sow and Reap...

Reap[Fold[If[#2>#1,Sow[#2],#2]&,First[#],Rest[#]]&@{1,4,3,2,5}][[2,1]]

l = {1, 4, 3, 2, 5};


Using ReplaceList:

(*Find elements greater than the one before*)

ReplaceList[Split[l, Less], {___, s : {a_, b__} /; a < b, ___} :> Last@s]

(*{4, 5}*)

(*Find elements smaller than the next one*)

ReplaceList[Split[l, Less], {___, s : {a_, b__} /; a < b, ___} :> First@s]

(*{1, 2}*)

(*Find a valley*)

ReplaceList[Split[l, Greater], {___, s : {a_, b_, c_} /; a > b, ___} :> Last@s]

(*{2}*)

(*Find a peak*)

ReplaceList[Split[l, Greater], {___, s : {a_, b_, c_} /; a > b, ___} :> First@s]

(*{4}*)

g[lis_] :=
Module[
{t1, t2},
t1 = Partition[lis, 2, 1];
t2 = Select[t1, #[[2]] > #[[1]] &];
t2[[All, 2]]
]


Functional form of a previous answer