# Making a list-function acting one-to one in a list of elements

Consider a pair of functions f1 and f2, and a vector {x,y}. I can get easily {f1[x],f2[y]} by doing MapThread[#1@#2 &,{f1,f2},{x,y}].

Now imagine that I have a function F defined as

F := {f1[#],f2[#]} &


Of course I cannot use the same procedure to get the same result, because now F is not a list of functions (as it was {f1,f2}), but a function itself that returns a list.

One way to get this result (and that admits generalization to longer lists) is

Diagonal[F/@{x,y}]


With this solution we build a whole matrix of elements of F acting on elements of the arguments list and we select the ones that we want.

I was wondering if there is a solution kind of like MapThread that gives the direct result, making act one-to-one the $n$-th element of the function with the $n$-th argument.

• Using := for F is strange here. Are you aware of the distinction between Set and SetDelayed? – Szabolcs Nov 25 '16 at 11:50
• I am. f1 and f2 are supposed to stand for concrete functions in this case (for example, F := {D[#,x],D[#,y]}&). – dpravos Nov 25 '16 at 11:56
• := is never needed if the right-hand side only has a Function (i.e. ...&). That's because Function already holds its arguments. It doesn't hurt to use := but the result will be exactly the same as it would have been with =. – Szabolcs Nov 25 '16 at 12:19
• Thanks, I had never thought about it. Is any of them recommended? – dpravos Nov 25 '16 at 15:20
• I use = for OwnValue assignments unless there is a special reason not to. If I see :=, I automatically look for a special reason. This is of course just my way of working. I can't think of a technical reason why := is bad here. – Szabolcs Nov 25 '16 at 15:35

For f = {f1[#], f2[#], f3[#]} &; you can also turn f into a list of functions using

Function/@f[[1]]


or using

First@MapAt[Function, f, {1, All}] (* thanks : Szabolcs *)
Thread[f] (* thanks: WReach *)


and then MapThread the resulting function list with the argument list:

ClearAll[mthreadF]

mthreadF[f, {x, y, z}]


{f1[x], f2[y], f3[z]}

Alternatively, you can use Inner:

ClearAll[innerF]
innerF = Inner[#@#2 &, Thread@#, #2, List] &;

innerF[f, {x, y, z}]


{f1[x], f2[y], f3[z]}

• The difficulty is evaluation control. The OP said that he actually has things such as {D[#,x],D[#,y]}&. Dealing with this, plus dealing with the various allowed syntaxes for Function makes this complicated. That is why I said that "There isn't a reasonable way ...". But looking at your post maybe it isn't quite as unreasonable ... How about First@MapAt[Function, f, {1, All}] for simple slot-based functions like what you considered? – Szabolcs Nov 25 '16 at 13:11
• @Szabolcs, thank you. First@MapAt[Function, f, {1, All}] is clever. I will update with your suggestion. – kglr Nov 25 '16 at 13:15
• I think that this is the answer I was looking for. The key resides in transforming the function f that returns a list of functions in the list of functions, solved with the MapAt. I found it quite elegant. – dpravos Nov 25 '16 at 15:46
• If we are allowed to assume that f is precisely of the form {...}&, then Thread[f] will perform the required conversion and thus mthreadF = MapThread[#@#2 &, {Thread[#], #2}] &;. – WReach Nov 25 '16 at 17:09
• @WReach, thank you ! I added your suggestion to the answer. – kglr Nov 26 '16 at 1:31

There isn't a reasonable way to avoid computing both f1 and f2 in this case. But we can avoid storing the whole matrix, which would (temporarily) take up a lot of memory. One way is MapIndexed.

f = {f1[#], f2[#]} &;

MapIndexed[Extract[f[#1], #2] &, {x, y}]
(* {f1[x], f2[y]} *)


Unless the lists are large enough that the matrix would take up a lot of memory, it's probably not worth bothering with this. I would choose your solution with Diagonal because I find it clearer than MapIndexed. This is, of course, just my personal preference.