Finding items satisfying a condition in a list using patterns
There are no List
s of length 3 in the input at level 1. So Cases
cannot find anything. However SequenceCases
can because it interprets lists as sequences.
SequenceCases[
{1, 2, 6, 3, 4, 8, 5},
{x_, y_, z_} /; (y > Max[x, z]) :> y,
Overlaps -> True
]
{6, 8}
ReplaceList
with a slight modification of the pattern in OP gives the desired result:
ReplaceList[{1, 2, 6, 3, 4, 8, 5}, {___, x_, y_, z_, ___} /; (y > Max[x, z]) :> y]
{6, 8}
The approach proposed in the question works well with a slight modification.
Cases[Partition[{1, 2, 6, 3, 4, 8, 5}, 3, 1], {x_, y_, z_} /; (y > Max[x, z]) :> y]
(* {6, 8} *)
There are many other approaches as well, for instance,
list = {1, 2, 6, 3, 4, 8, 5};
MapThread[If[#1 > Max[#2, #3], #1, Nothing] &,
{list[[2 ;; -2]], list[[1 ;; -3]], list[[3 ;; -1]]}]
(* {6, 8} *)
Timing
Runtime for the MapThread
solution with a list
of length of 40000 is, for instance,
list = RandomInteger[{0, 9}, 40000];
AbsoluteTiming[MapThread[If[#1 > Max[#2, #3], #1, Nothing] &,
{list[[2 ;; -2]], list[[1 ;; -3]], list[[3 ;; -1]]}][[1 ;; 10]]]
about 0.06 seconds on my computer and increases approximately linearly with the length of list
. The solution using Cases
and Partition
requires about the same amount of time. Surprisingly, the solution with ReplaceList
is about two orders of magnitude slower and increases approximately quadratically with the length of list
. The solution using SequenceCases
is many orders of magnitude slower and increases at least cubically with the length of list
.