6
$\begingroup$

I have used Mathematica for two years.And usually,I can use single pure function(#&) rightly.However,for the use of multiple pure function,I always make all kinds of mistake.

For example

I want exact the number that in some interval,shown as below:

Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[{0, 1}], #] &] 
(**==>{1})

Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[{1, 4}], #] &]
(**==>{1,2,3,4})

Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[{3, 4}], #] &]
(**==>{3,4})

So I want to combine them as below:

Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[#]&, #] &] /@{{0, 1},{1, 4},{3, 4}}
(*{{}[{0, 1}], {}[{1, 4}], {}[{3, 4}]}*)

Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[#]&, #]]& /@{{0, 1},{1, 4},{3, 4}}
(*{{}, {}, {}}*)

So my question is how to use multiple pure functions correctly?

$\endgroup$
  • 1
    $\begingroup$ In this case it would be a little clumsy to go with functional style all the way. How about making it simpler with Table[Select[{1, 2, 3, 4, 5}, IntervalMemberQ[Interval[i], #] &], {i, {{0, 1}, {1, 4}, {3, 4}}}]? $\endgroup$ – Jens Jul 6 '14 at 1:33
  • $\begingroup$ @Jens,+1,Good ideal.However,I want to use this case that I encounter today to improve my ability of using multiple pure function.In Kuba's answer,I admire he using multiple pure function masterly!Composition[ Map[If[#[[2]] - #[[1]] < 10^\[Delta], ## &[], Mean[#]] &, #, {2}] &, Partition[#, 2, 1] & /@ # &, Union /@ # &, Transpose] $\endgroup$ – user8336 Jul 6 '14 at 1:46
  • $\begingroup$ Yes, that's all possible, but it's very hard to read - perhaps more difficult to read than it is to write it... And (#&) is basically just shorthand for Function anyway. $\endgroup$ – Jens Jul 6 '14 at 1:51
  • $\begingroup$ @Jens,Thanks for your suggestion sincerely!Indeed,I also think it is difficult to understand code when many #& appear in one line code. $\endgroup$ – user8336 Jul 6 '14 at 1:56
  • 1
    $\begingroup$ Just to reinforce the point in the answer below. This shows the two # do not clash when using Function as in data = {1, 2, 3, 4, 5}; intervals = {{0, 1}, {1, 4}, {3, 4}}; Map[Select[data, #] &, (Function[i, IntervalMemberQ[Interval[#], i]] & /@ intervals)] The second # is bounded to the Function and the outer # does not see it. $\endgroup$ – Nasser Jul 6 '14 at 2:04
7
$\begingroup$

This is a way to resolve the conflict between the two different # instances in your construct, using pure functions only:

Select[{1, 2, 3, 4, 5}, 
   Function[i, IntervalMemberQ[Interval[#], i]]] & /@ {{0, 1}, {1, 
   4}, {3, 4}}

(* ==> {{1}, {1, 2, 3, 4}, {3, 4}} *)
$\endgroup$
4
$\begingroup$

Another alternative,

list = Range[5];

intervals = {{0, 1}, {1, 4}, {3, 4}};

Pick[list, #] & /@ Outer[
  IntervalMemberQ[Interval[#1], #2] &,
  intervals, list, 1]

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

$\endgroup$
1
$\begingroup$

I would prefer using Jens' approach -- using pure functions with named arguments. However, you can also use the following alternatives:

intervals = {{0, 1}, {1, 4}, {3, 4}};

With[{i = #}, Select[Range[5], IntervalMemberQ[Interval[i], #] &]] & /@ intervals

or

Select[Range[5], With[{i = #}, IntervalMemberQ[Interval[i], #] &]] & /@ intervals

or

(Select[Range[5],  IntervalMemberQ[i, #] & /. i -> Interval[#]]) & /@ intervals

to get

{{1}, {1, 2, 3, 4}, {3, 4}} 
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy