Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have the following working construction:

Select[ln125, # == Nearest[ln125, 551.748][[1]] &]

Here, ln125 is a one dimensional list.

What I want further is to apply this construction not only to ln125, for example, but for a list of {ln125,ln126,ln127}.

Let's say,

f[list_]:=Select[list, # == Nearest[list, 551.748][[1]] &]

I want to do this:

f /@ {ln125,ln126,ln127}.

The question is: is it possible to acheive my goal only using pure functions? That is, without defining dummy function (f in my case)? The problem is that definition of f already has pure function (as a criteria for Select) and, thus, there should be two pure function of different depths (don't know how to name it correctly) at once. In other words, I want to turn the list variable into # but in a way that Mathematica can distinguish which # goes with each different pure function.

share|improve this question
2  
Yes if you use the full form Function. –  image_doctor Dec 26 '12 at 1:48
add comment

4 Answers

You can use the form Function[{x,y,z}, body] to define a pure function with formal parameters x,y,z ( see Documentation >> Function)

Let

 lists = {ln125, ln126, ln127} = RandomReal[{0, 10}, {3, 10}]
 (* {{1.72286, 5.24912, 8.87257, 5.77593, 6.31276, 1.77914, 2.06393,
      0.328725, 9.46436, 4.96257}, 
     {1.71171, 2.54337, 5.93807, 9.46774,  6.99601, 2.76927, 7.58995,
      1.25785, 2.09789, 9.32326}, 
     {6.9821, 8.62002, 2.0763, 8.9402, 4.36728, 3.8571, 4.4175,
      7.15698, 7.64633, 5.23772}} *)

Define, (with 4. playing the role of 551.748 in your example):

 f2 = Function[{x}, Select[x, # == Nearest[x, 4.][[1]] &]]
 f2 /@ lists
 (* {{4.96257}, {2.76927}, {3.8571}} *)   

or

  f3 = With[{temp = Nearest[#1, 4.`][[1]]}, Select[#1, # == temp &]] &
  f3 /@ lists
  (* {{4.96257}, {2.76927}, {3.8571}} *)   
share|improve this answer
add comment

In can be done in a terse way with nested pure functions:

lists = RandomReal[{0, 10}, {3, 10}]

{{3.35338, 2.82572, 0.152277, 1.19036, 9.88211, 6.55398, 8.11855, 0.793288, 9.04547, 6.42518}, {4.95417, 7.73982, 5.58323, 3.09912, 5.44546, 8.88474, 2.67437, 8.20605, 4.55918, 1.95303}, {2.53793, 6.67839, 8.71033, 8.4877, 0.634367, 7.99796, 4.74131, 0.679337, 8.29468, 9.91209}}

Select[#, With[{aList = #}, # == Nearest[aList, 5.][[1]] &]] & /@ lists

{{6.42518}, {4.95417}, {4.74131}

Using With to insert expressions into Function, which has the HoldAll attribute, is trick that is useful to keep in mind.

share|improve this answer
add comment

To clarify one of the answers. Note there is no way to distinguish both # inside # == Nearest[#, 551.748][[1]] in

Select[#, # == Nearest[#, 551.748][[1]] &] &

as you already noted. So, you need to give the outermost # a name and Function[...] is just for that. This one works:

Function[{l}, Select[l, # == First[Nearest[l, 551.748]] &]]

Personally, I don't like the With trick above: if you need to give it a name, use the language construct for that. Then you do:

Function[{l}, Select[l, # == First[Nearest[l, 551.748]] &]] /@ {ln125,ln126,ln127}

Note that a Function[...] is already a (...&), so you don't need the usual ...& /@..., just Function[...] /@.

P.S If you do this often, this is, fix a value (i.e. First[Nearest[l, 551.748]]) inside another function of two or more parameters (i.e. Equal in your case) to have a function of the free parameters, then the following can be useful

FixCurry[f_, v_] := f[v, ##] &;

So, FixCurry[Equal, 3] is Equal[3,#] &. And this can be used in your case like

Select[#, FixCurry[Equal, First[Nearest[#, 5.]]]] & /@ {ln125,ln126,ln127}

which avoids the inner (..&) via the FixCurry construct. If you wonder how this could be used in other contexts, notice that the first argument to FixCurry can be a pure function with the (...&) syntax. In your example, more verbose but equivalent,

Select[#, FixCurry[#1 == #2 &, First[Nearest[#, 5.]]]] & /@ {ln125,ln126,ln127}

Hope it helps.

share|improve this answer
add comment

The "working construction" Select[list, # == Nearest[list, value][[1]] &] will give a list of the form {nearestvalue, nearestvalue, ...}, in which the nearest value is simply repeated the number of times it appears in list.

If lists contains several lists and all you want is the value in each list that is nearest to value then

nearestvals = Nearest[#, value][[1]]& /@ lists

will give you a list of those values. If you also want the repeat counts then

MapThread[{#2, Count@##}&, {lists, nearestvals}]

will give {{nearestvalue, count}, {nearestvalue, count}, ...}, with a pair for each list in lists.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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