Removing pairs that meet a given criterion from a list [duplicate]

Let $(x_{min},x_{max})$ and $(y_{min},y_{max})$ represent lowerbound and upperbound acceptable values for some coordinate $c_i$.

Setting $x_{min} = y_{min} = 1$ & $x_{max} = y_{max} = 9$, how can I take a list of values, e.g.:

val = {{0, 10}, {2, 10}, {4, 4}, {5, 6}, {10, 4}};


and use DeleteCases to get rid of coordinates such as {0, 10}, {2,10}, & {10,4} (the examples in the above list) where either the $x$ or $y$ component of a pair is outside of the specified upper and lower bounds for acceptable values? Is DeleteCases an appropriate tool for large arrays?

-

marked as duplicate by Jens, Michael E2, Artes, m_goldberg, Sjoerd C. de VriesJun 30 '13 at 22:12

You can achieve the same end with DeleteCases or Cases.

f signals a coordinate that is out of bounds.

g signals that a coordinate is in bounds.

f[n_] := n < 1 \[Or] n > 9
g[n_] := 1 <= n <= 9


Four ways to filter out the outlying points:

v[k] generates 10^k values between {0, 0} and {10, 10})

v[k_] := Table[{r, r}, {10^k}];

1. Delete the points that have an out-of-bounds coordinate.

DeleteCases[v[k], {x_, y_} /; f[x] \[Or] f[y]]

2. Delete the points that are not in-bounds.

DeleteCases[v[k], {x_, y_} /; \[Not] (g[x] \[And] g[y])]

3. Keep points that are not out-of-bounds.

Cases[v[k], {x_, y_} /; \[Not] (f[x] \[Or] f[y])]

4. Keep points that are in-bounds.

Cases[v[k], {x_, y_} /; (g[x] \[And] g[y])]


Timings

    r = Table[{AbsoluteTiming[DeleteCases[v[k], {x_, y_} /; f[x] \[Or] f[y]];],
AbsoluteTiming[DeleteCases[v[k], {x_, y_} /; \[Not] (g[x] \[And]g[y])];],
AbsoluteTiming[Cases[v[k], {x_, y_} /; \[Not] (f[x] \[Or] f[y])];],
AbsoluteTiming[Cases[v[k], {x_, y_} /; (g[x] \[And] g[y])];]}, {k,  3, 7}]
Grid@Prepend[ r[[All, All, 1]], {"Delete f", "Delete not-g", "Cases not-f", "Cases g"}]


The results with DeleteCases and Cases (from 10^3 to 10^7 points) show that DeleteCases with function g gives the fastest analysis.

-

An alternative is to use Select to retain only those elements you desire:

val = {{0, 10}, {2, 10}, {4, 4}, {5, 6}, {10, 4}};
Select[val, 1 <= First[#] <= 9 && 1 <= Last[#] <= 9 &]

{{4, 4}, {5, 6}}


In this case, all those with values outside the specified ranges are removed, leaving only the desired pairs.

-