1
$\begingroup$

How can I modify my function so that it will take a list of ordered pairs, and return just the pairs whose first value is greater than or equal to a given minimum and less than or equal to a given maximum value?

This is the initial code:

function2[list_, max_] := Select[list, # <= max &]

I know what to do for the order pairs. I just don't know how to use multiple conditions with Select.

$\endgroup$
  • $\begingroup$ In this case you can get away with a three argument form of LessEqual (e.g. a <= b <= c), but in general you can just use And for multiple conditions (e.g. cond1 && cond2 && ...) $\endgroup$ – ngenisis Feb 8 '17 at 1:30
2
$\begingroup$
data = {{3, 4}, {5, 6}, {2, 9}, {1, 8}};
Select[data, 2.5 <= #[[1]] <= 3.5 &]

or

myselector[data_List, min_, max_] := 
   Select[data, min <= #[[1]] <= max &]
$\endgroup$
2
$\begingroup$

Select does not auto-compile so where possible a vectorized approach will be faster.

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

sel[v_, min_, max_] := UnitStep[(v - min) (max - v)]

mask = sel[data[[All, 1]], 2, 4]

Pick[data, mask, 1]
{0, 1, 1, 1, 0}

{{2, 1}, {3, 1}, {4, 1}}

This may be done in a single "line" if you prefer but I broke it down for intelligibility.

Performance comparison:

big = RandomInteger[9, {1*^6, 2}];

Pick[big, sel[big[[All, 1]], 2, 4], 1]   // Length // AbsoluteTiming

Select[big, 2 <= #[[1]] <= 4 &]          // Length // AbsoluteTiming
{0.0367064, 300370}

{1.10751, 300370}

Related questions:

$\endgroup$
1
$\begingroup$

David's answer is more efficient for your particular set of conditions, but in general you can chain conditions with And ( && ). In your case, it would look like this.

f[data_, min_, max_] := Select[data, Module[{u = First[#]}, min <= u && u <= max] &]
data = {{3, 4}, {5, 6}, {2, 9}, {1, 8}};
f[data, 2, 3]

{{3, 4}, {2, 9}}

$\endgroup$
1
$\begingroup$
data = {{3, 4}, {5, 6}, {2, 9}, {1, 8}};

Using GroupBy:

func[lst_, min_, max_] := True /. GroupBy[lst, min <= #[[1]] <= max &]

Using Reap/Sow:

rp[lst_, min_, max_] := 
 Reap[Sow[#, min <= #[[1]] <= max] & /@ lst, True, #2 &][[-1, 1]]

Then:

func[data, 2, 3]
rp[data, 2, 3]

both yield: {{3, 4}, {2, 9}}

$\endgroup$

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