46

I need a table with the elements made of pure functions and list elements. This is a simplified example:

I need a list as:

{a[[1]]*Sin[#]&,a[[2]]*Sin[#]&,a[[3]]*Sin[#]&}

and, my failed try is : Table[a[[i]]*Sin[#]&,{i,3}]

Why is the failure and how can I improve it?

Kuba
  • 136,707
  • 13
  • 279
  • 740
yulinlinyu
  • 4,815
  • 2
  • 29
  • 36

4 Answers4

45

Function has the attribute HoldAll, so the reference to i in the Table expression will not be expanded.

However, you can use With to inject the value into the held expressions:

Table[With[{i = i}, a[[i]]*Sin[#] &], {i, 3}]
{a[[1]] Sin[#1] &, a[[2]] Sin[#1] &, a[[3]] Sin[#1] &}

This issue will be present not only for Function but for all expressions that hold their arguments (via attributes like HoldFirst) -- for example: Plot, Dynamic, RuleDelayed (:>) etc.

The solution using With is mentioned in the tutorial "Introduction To Dynamic / A Good Trick to Know".

WReach
  • 68,832
  • 4
  • 164
  • 269
11

. . . & is a held expression. (Function has attribute HoldAll.)

Injector pattern to the rescue:

Range@3 /. i_Integer :> (a[[i]] Sin[#] &)

Replace[Range@3, i_ :> (a[[i]] Sin[#] &), 1]

Table[j /. i_ :> (a[[i]] Sin[#] &), {j, 3}]

Or using \[Function] and Array:

Array[i \[Function] (a[[i]] Sin[#] &), 3]

In this case you could do the replacement the other direction but you will need to hold i to protect it from a global value:

Table[a[[i]] Sin[#] & /. HoldPattern[i] -> j, {j, 3}]

Or use Block:

Block[{i},
  Table[a[[i]] Sin[#] & /. i -> j, {j, 3}]
]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
8

This works, but only because j is undefined:

Table[(a[[j]]*Sin[#] &) /. j -> i, {i, 3}]

(if we do j = 5; Table[(a[[j]]*Sin[#] &) /. j -> i, {i, 3}] then it fails; one could localize this with Module to get it to work anyway).

Or, if you hate brevity and compactness:

cF = Function[{j}, a[[j]]*Sin[#] &];
Table[
 cF[j],
 {j, 1, 3}
 ]

Personally I'd use either this last form or WReach's/Rojo's way.

acl
  • 19,834
  • 3
  • 66
  • 91
  • @LeonidShifrin thanks. Yes, that it would need to be localized is what I meant (it's accidental that j is undefined). Bad choice of words, I suppose (and, oops, I hadn't seen your comment... why not an answer?) – acl Jul 01 '12 at 18:13
  • I've already answered a variant of this question twice (in the links I give in the comments to the question). Trying not to be greedy :-) – Leonid Shifrin Jul 01 '12 at 18:15
5

With Mathematica 10, you can also do this by

Activate@Table[Inactivate[a[[i]]*Sin[#] &], {i, 3}]
matheorem
  • 17,132
  • 8
  • 45
  • 115