# Select with test function that depends on # [duplicate]

I'm trying to teach myself to use pure functions and slots as much as possible. Here is my problem.

I have a list:

RandomSeed[314];
l = RandomInteger[{1, 10}, 20]
(*{3, 6, 1, 4, 4, 6, 1, 6, 3, 6, 8, 10, 8, 7, 5, 4, 8, 4, 4, 8}*)


Now I want to select all elements that equal 1 by using Select:

Select[l, # == 1 &]
(*{1, 1}*)


Then I want to get two lists, one with 8s and second with 1s:

test[p_] := p == # &;
Select[l, test[#]] & /@ {8, 1}
(*{{8, 8, 8, 8}, {1, 1}}*)


How can I do it without introducing test[p_]? In other words I need Select's second argument to depend on "another" slot #, not the one that will be substituted by list elements during iteration. The closest question I was able to find is Second level depth pure function?, but I think my question is slightly different, because I don't have to put slot in the first argument of Select

Thanks a lot to everybody who answered in comments.

leo[l_] := Reap[Sow[#, #] & /@ l, 1 | 8, #2 &][[2]];
jm[l_] := Function[p, Select[l, # == p &]] /@ {8, 1};
kgl[l_] := Select[l, Function[x, x == #]] & /@ {8, 1};
mar[l_] := With[{p = #}, Select[l, # == p &]] & /@ {8, 1};


Out of curiosity I decided to run simple benchmark to check performance

Benchmark[f_, n_] := Module[{l, results, samples},
RandomSeed[314];
samples = Table[RandomInteger[{1, 100}, n], {10}];
results = Table[First@AbsoluteTiming[f[l]], {l, samples}];
Mean[results]];
testRange = 10^# &@{3, 4, 5, 6};
TableForm[
Table[Benchmark[fun, n]/n, {fun, {leo, jm, kgl, mar}}, {n,
testRange}],
TableHeadings -> {{"leo", "jm", "kgl", "mar"}, testRange}]


The results are normalized over list length. Interestingly kgl[] is about two times slower than jm[].

IMHO the Select[l, Function[x, x == #]] & /@ {8, 1} (by @kglr) is the most visually appealing.

It was also asked why do I care if all I need is just making two simple Selects?

I think it's more clear and concise to have one line that does something twice rather than having two almost identical lines. My original example is oversimplified probably.

Imagine I want to select all prime numbers and also all numbers that are prime squared. If I use syntax by @kglr I can do

{primes, primeSq} =
Select[l, Function[x, #[x]]] & /@ {PrimeQ, PrimeQ@Sqrt[#] &}


Which is very self explanatory.

• With[{p=#}, Select[l, # == p &]]& /@{8,1} is one possibility. Or use Function. Mar 18, 2016 at 18:03
• Why not Function[p, Select[l, # == p &]] /@ {8, 1}? Mar 18, 2016 at 18:03
• I retracted the close vote. However, note that as soon as you start categorizing things, your operation is no longer a simple select, so there is no reason to expect that Select without additional steps can handle it - categorization is semantically different from selection. You can use Reap and Sow with specific tags: Reap[Sow[#, #] & /@ l, 1 | 8, #2 &][[2]], which maps mor directly to your needs, it seems. Mar 18, 2016 at 18:21
• Select[l, Function[x, x == #]] & /@ {8, 1}?
– kglr
Mar 18, 2016 at 19:00
• @BlacKow, from the Slot docs: "When pure functions are nested, the meaning of slots may become ambiguous, in which case parameters must be specified using an explicit Function construction with named parameters." Mar 18, 2016 at 20:01

l = {3, 6, 1, 4, 4, 6, 1, 6, 3, 6, 8, 10, 8, 7, 5, 4, 8, 4, 4, 8};