Select from list elements greater than next element

Given

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0}


I want to get all the elements which are greater than the right neighbor. The result would be

{3, 8, 6, 9, 4, 5}


I can do it by

t2 = Partition[t1, 2, 1]
Select[t2, #[[1]] > #[[2]] &][[All, 1]]


But I am looking for a solution like

Select[t1, #1 > #2 &]


which does not work

• Most[Last /@ Split[t1, Less]]? Commented Aug 16, 2023 at 17:43

1.

Pick[Most @ t1, UnitStep @ Differences @ t1, 0]

{3, 8, 6, 9, 4, 5}


2.

t1[[RandomPrivatePositionsOf[UnitStep @ Differences @ t1, 0]]]

{3, 8, 6, 9, 4, 5}

• Pick[Most @ t1, Sign @ Differences @ t1, -1] Commented Aug 23, 2023 at 13:35

We MapApply Greater on partitions of the list with offset, then use Pick to select all the valid elements.

list = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};

Pick[Most@list, Greater @@@ Partition[list, 2, 1], True]

(* Out: {3, 8, 6, 9, 4, 5} *)


Performance

Here is the performance of this answer compare to others on a list of 1,000 random integers in Mathematica 13.3:

kglr's Pick - 1 0.000014 30880
kglr's Pick - 2 0.000015 22632
Ben's Pick 0.00041 184984
Syed Split 0.00044 93920
ydd's Ordering 0.00082 124112
Daniel Huber's MapIndexed 0.002 281848
lericr's SequenceCases 1.9 4522768

Maybe this?

SequenceCases[t1, {a_, _}?(Apply[Greater]) :> a, Overlaps -> True]

• A bit neater perhaps: SequenceCases[list, ({a_, b_} /; (a > b)) :> a, Overlaps -> True] Commented Aug 16, 2023 at 19:07

You can do this using "MapIndexed". This delivers not only the list element, but as second argument also its position. Increasing this by one, you can reach the next element. Look it up in the help.

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};
MapIndexed[If[#1 > t1[[#2[[1]] + 1]], #1, Nothing[]] &, Most@t1]

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};


Using FoldPairList:

FoldPairList[If[#1 > #2, {#1, #2}, {, #2}] &, t1] /. Null -> Nothing


Using Split:

Split[t1, #1 > #2 &] // Map[Most] // Flatten


or alternatively:

Split[t1, Greater] // Map[Most] // Flatten


First /@ Select[Partition[t1, 2, 1], First@# > Last@# &]


or using the operator form:

Map[First][Select[First@# > Last@# &][Partition[t1, 2, 1]]]


Result

{3, 8, 6, 9, 4, 5}

Perhaps the DeleteAdjacentDuplicates can be abused:

list={3,2,8,6,1,9,4,1,5,0};


Could take the differences in the ordering of the ordering and select where it's less than 0

t1[[Position[Differences@Ordering@Ordering[t1], n_ /; n < 0] //
Flatten]]


Basically the same thing but using RotateLeft:

t1[[Position[Most[t1 - RotateLeft[t1]], n_ /; n > 0]//Flatten]]


Using Sow and Reap.

fun[u_] :=
Reap[Sow @@@
ArrayPad[Sign@*Differences@u, {0, 1}, "x"]}], -1, #2 &][[2, 1]]


Testing:

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0}
fun[t1]


yields: {3, 8, 6, 9, 4, 5}

# -> fun[#] & /@ RandomInteger[10, {10, 10}] // Column


Another way using GroupBy and Lookup:

Lookup[GroupBy[Partition[t1, 2, 1], #[[1]] > #[[2]] &, #[[All, 1]] &], True]

(*{3, 8, 6, 9, 4, 5}*)


Single pass with a loop, no copy:

l = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0} ;
Reap[
Do[
With[
{a = l[[i]], b = l[[i + 1]] },
If[a > b, Sow[a]]
],
{i, 1, Length[l] - 1}
]
] // Last // First


Another method:

t1[[Lookup[-1]@PositionIndex@Sign@Differences@t1]]

(* {3, 8, 6, 9, 4, 5} *)


Or, a slight variant with UnitStep instead of Sign:

t1[[Lookup[0]@PositionIndex@UnitStep@Differences@t1]]

Cases[{a_, b_} /; a > b :> a] @ Partition[list, 2, 1]


{3, 8, 6, 9, 4, 5}

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};

k={t1[[#]],(t1[[#]]-t1[[#+1]])}&/@Range[Length[t1]-1];

First/@Select[k,#[[2]]≥0&]


Resultat

{3,8,6,9,4,5}


Autre code:

t1 = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};

k=t1-Insert[TakeList[t1,{1,All}][[2]],0,-1];

Select[Sign[k]*t1,#>0&]


Resultat

{3,8,6,9,4,5}


This code is more speed and simple:

Select[-Sign[Insert[Differences[t1],-1,-1]]*t1,#>0&]

list = {3, 2, 8, 6, 1, 9, 4, 1, 5, 0};


Using SequenceSplit (new in 11.3)

First /@ Catenate @ SequenceSplit[Partition[list, 2, 1], {{a_, b_}} /; a <= b]


{3, 8, 6, 9, 4, 5}