7
$\begingroup$

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?

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

6 Answers 6

10
$\begingroup$

@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!

$\endgroup$
3
  • 2
    $\begingroup$ +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] $\endgroup$ Commented Dec 5, 2014 at 13:05
  • 1
    $\begingroup$ wow!Just updated my mathematica to V10, never seen MovingMap[] before,it's cool! $\endgroup$
    – QhelDIV
    Commented Dec 6, 2014 at 6:21
  • $\begingroup$ Well, took me only six years to discover MovingMap[]. $\endgroup$ Commented Jun 13, 2020 at 6:38
2
$\begingroup$

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}

$\endgroup$
2
$\begingroup$
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}

$\endgroup$
1
$\begingroup$

Because I like Sow and Reap...

Reap[Fold[If[#2>#1,Sow[#2],#2]&,First[#],Rest[#]]&@{1,4,3,2,5}][[2,1]]
$\endgroup$
1
$\begingroup$
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}*)
$\endgroup$
0
$\begingroup$
g[lis_] :=
  Module[
    {t1, t2},
    t1 = Partition[lis, 2, 1];
    t2 = Select[t1, #[[2]] > #[[1]] &];
    t2[[All, 2]]
  ]

Functional form of a previous answer

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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