16

Here is a pure function with multiple slots:

(#1^2 + #2^2)&[3, 4]

25

But how can I map that pure function over lists of values? For example, say I want to map (#1^2 + #2^2)& over x = {1, 2, 4} and y = {3, 4, 6}. I have tried the following expressions, but none of them work:

Map[(#1^2 + #2^2) &, {1, 2, 4}, {3, 4, 6}]
Map[(#1^2 + #2^2) &, {{1, 2, 4}, {3, 4, 6}}]
Map[(#1^2 + #2^2) &, {{1, 3}, {2, 4}, {4, 6}}]

The result I expect is obviously {10, 20, 52}.

Could some one help me with this?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
yanfyon
  • 594
  • 4
  • 15

3 Answers3

17
MapThread[#1^2 + #2^2 &, {x, y}]
Zviovich
  • 9,308
  • 1
  • 30
  • 52
12

I like the following very much

{x, y} = {{1, 2, 4}, {3, 4, 6}};
(#1^2 + #2^2) & @@@ Transpose[{x,y}]

Another thing which is highly unused is to attach Attributes to pure Functions

Function[{a, b}, a^2 + b^2, {Listable}][x, y]

You can stick with the Slot notation too, but you have to tell then that the variables in Function is a Null list which might look too awkward for some users (but I give this as dedication to Leonid, who uses this quite a bit)

Function[Null, #1^2 + #2^2, {Listable}][x, y]

and to really mess it up, I'd like to remind everyone, that you don't need to put the Null explicitly. Therefore, this is completely valid syntax

Function[, #1^2 + #2^2, {Listable}][x, y]
Michael E2
  • 235,386
  • 17
  • 334
  • 747
halirutan
  • 112,764
  • 7
  • 263
  • 474
  • Isn't attaching {Listable} the same as using MapThread from PatoCriollo's answer? – BlacKow Jun 26 '13 at 23:01
  • @BlacKow Nope, try to do this with MapThread: Function[{x, y}, x + y, {Listable}][1, {1, 2, 3}]. On the other hand with MapThread you can specify the level of depth. – halirutan Jun 26 '13 at 23:06
  • I'm really just starting to learn Mathematica so I have a confusing mix of Map,Apply,Thread in my head. I was just saying that there are two different families of possible solutions: based on Threading and based on Applying. Is it correct? – BlacKow Jun 26 '13 at 23:15
  • 1
    @BlacKow sort of. Consider Map to be your generic method for transforming everything in a list/expression, e.g. f /@ a[q,r,s] becomes a[f[q], f[r], f[s]] Apply changes the Head of an expression, e.g. Times@@(a+b) becomes Times[a, b]. So, it does not work on atomic expressions, i.e. if AtomQ@e == True Apply won't work on it. (Map doesn't have that restriction.) Otherwise, it is similar to MapThread. Thread, however, is in some ways a generic distribution function for lists, e.g. Thread[a -> {q, r}] becomes {a->q, a->r}. So, subtly different applications. – rcollyer Jun 27 '13 at 03:11
  • @rcollyer thank you, this was my thought as well. Substituting the Head versus Mapping – BlacKow Jun 27 '13 at 03:15
1

Referring to the responses, maybe it is more elegant this way?

For single slot:

#^2 & @ {1,2,4}

[Out]={1, 4, 16}

For multiple slots:

(#1^2 + #2^2) & @@ {{1, 2, 4}, {3, 4, 6}}

[Out]= {10, 20, 52}

The following codes have same output:

MapThread[(#1^2 + #2^2) &, {{1, 2, 4}, {3, 4, 6}}]

Apply[(#1^2 + #2^2) &, {{1, 2, 4}, {3, 4, 6}}]

It seems that Apply and MapThread are exchangeable in this case!

yanfyon
  • 594
  • 4
  • 15