# Slot # corresponding to subset of a list in select

Is it possible to use # in the select function preserving the structure of the list?

Here an example of what I mean. Let's say I want to select all the pairs where the first element is 1:

data1 = {{1, 2}, {1, 3}, {3, 4}, {4, 4}, {5, 2}};
data2 = {{1, 1}, {1,5}, {3, 5}};
all = {data1, data2};

The output of the function would be:

{{{1,2},{1,3}},{{1,1},{1,5}}}

I tried with Select but I'm not able to preserve the list structure. Here some (failed) attempt:

Select[all, #[[1, 1]] == 1 &]

with the output:

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

because, as far as I understand, # refers to the elements of the outer list (which are data1 and data2).

Or

Select[Flatten[all, 1], #[[1]] == 1 &]

with the output

{{1, 2}, {1, 3}, {1, 1}, {1, 5}}

but the list structure is not preserved.

Any tips? I just started using functional programming and I often get stuck on this simple (I assume) stuff.

Select[#, #[[1]] == 1 &] & /@ all
Select[#[[1]] == 1 &] /@ all (* thanks: Mr.Wizard *)
Pick[all, #[[1]] == 1 & /@ # & /@ all]
Pick[all, all[[All, All, 1]], 1]
Map[If[#[[1]] == 1, #, ## &[]] &, all, {2}]

all give

{{{1, 2}, {1, 3}}, {{1, 1}, {1, 5}}}

• Also operator form: Select[#[[1]] == 1 &] /@ all Commented Jul 23, 2017 at 9:29
• thank you @Mr.Wizard.
– kglr
Commented Jul 23, 2017 at 9:39
• IMO, Pick makes a lot of sense here, good one :) Commented Jul 23, 2017 at 10:58
• Amazing, thank you guys! :D Commented Jul 23, 2017 at 18:25
• @Marius I like Pick too, especially its performance on packed arrays compared to Select/Cases, but with the caveat that it can at times be confusing, e.g. (4946), (59272), (119223). Commented Jul 24, 2017 at 1:14

At least for the example given:

Cases[{1, _}] /@ all
{{{1, 2}, {1, 3}}, {{1, 1}, {1, 5}}}
DeleteCases[all, {Except[1], _}, 2]

{{{1, 2}, {1, 3}}, {{1, 1}, {1, 5}}}

Or, more generally:

DeleteCases[{all, all}, {Except[1], _?AtomQ}, -1] // MatrixForm

You may use Query with Select.

Query[All, Select[First@# == 1 &]]@all
{{{1, 2}, {1, 3}}, {{1, 1}, {1, 5}}}

Hope this helps.

Thank you everyone for your answers, I took all of them and tested their efficiency, below the results with absolute timing, acting on randomly generated lists:

data1 = Transpose@{RandomInteger[10, {10^5}], RandomInteger[10, {10^5}]};
data2 = Transpose@{RandomInteger[10, {10^5}], RandomInteger[10, {10^5}]};
all = {data1, data2};

Select[#, #[[1]] == 1 &] & /@ all
0.216706

Select[#[[1]] == 1 &] /@ all
0.218946

Pick[all, #[[1]] == 1 & /@ # & /@ all]
0.404901

Pick[all, all[[All, All, 1]], 1]
0.004603

Map[If[#[[1]] == 1, #, ## &[]] &, all, {2}]
0.356775

Select[#[[1]] == 1 &] /@ all
0.237376

Cases[{1, _}] /@ all
0.078295

DeleteCases[all, {Except[1], _}, 2]
0.104606

Query[All, Select[First@# == 1 &]]@all
0.183894