# Mapping function across its arguments

Is there a more elegant way to do the following? (The code should be f-less and replacement-less)

expr = f[a, b, c];
Head@# /@ List @@ # &@expr


{f[a], f[b], f[c]}


If it were a list of arguments then elegant solution would be:

expr = f[{a, b, c}];


{f[a], f[b], f[c]}


But that is not the case. My expression is f[a, b, c] not f[{a, b, c}].

The shortest code I found was f /@ List @@ expr but this contains f which I want to be avoided.

• Replace[head_[args___] :> head /@ {args}] @ expr is about as elegant as I think it'll get. It's not exactly as standard transformation you encounter regularly. Commented Feb 14 at 17:07
• It is nice, l like it. But I have just added that the code should be without any replacements. Commented Feb 14 at 17:10

Tuples[expr, 1]

(* {f[a], f[b], f[c]} *)

• Wow, I did not expect Tuples can be used this way. I guess nobody can beat you answer. Commented Feb 14 at 19:24
• The same code but in one character shorter form: expr~Tuples~1. Commented Feb 14 at 21:38

Using Subsets:

expr = f[a, b, c];

Subsets[expr, {1}]

(*{f[a], f[b], f[c]}*)


Or using Subsequences:

Subsequences[expr, {1}]

(*{f[a], f[b], f[c]}*)


Or using Outer and Level:

Level[Outer[Head@#, #, 1], {1}] &@expr

(*{f[a], f[b], f[c]}*)


Or using Outer and Cases:

Cases[Outer[Head@#, #, 1] &@expr, s1_@s2_]

(*{f[a], f[b], f[c]}*)

Operate[Map[#]@*List &, expr]


Some alternatives:

f[a, b, c] // #[[0]] /@ Level[#, 1] &

(* {f[a], f[b], f[c]} *)

f[a, b, c] // #[[0]] /@ List @@ # &

(* {f[a], f[b], f[c]} *)


Sharper, not shorter:

f[a, b, c] // #[[0]] /@ ({##} & @@ #) &

(* {f[a], f[b], f[c]} *)

expr[[0]]/@{Delete[0][expr]}

(* {f[a],f[b],f[c]} *)


or

Thread[Head[expr][{Delete[expr,0]}]]

(* {f[a],f[b],f[c]} *)

(* {f[a],f[b],f[c]} *)

expr = f[a, b, c];


Using BlockMap

BlockMap[# &, expr, 1]


Using Partition

List @@ Partition[expr, 1]


Using Span

Array[expr[[# ;; #]] &, Length@expr]


All of them give:

{f[a], f[b], f[c]}

expr = f[a, b, c];

expr[[0]] /@ (expr[[#]] & /@ Range[Length[expr]])
(* {f[a], f[b], f[c]} *)

Take[expr, {#}] & /@ Range[Length[expr]]
(* {f[a], f[b], f[c]} *)

Array[expr[[0]][expr[[#]]] &, Length[expr]]
(* {f[a], f[b], f[c]} *)
$$$$

expr = f[a, b, c];

expr[[0]] /@ List @@ expr


{f[a], f[b], f[c]}

First @ Cases[expr, x_[y__] :> x /@ {y}, {0}]


{f[a], f[b], f[c]}

expr /. x_[y__] :> x /@ {y}


{f[a], f[b], f[c]}

Thread[f[a, b, c] /. y_[x__] -> y[{x}]]


??

Permutations[expr,{1}]


Or :

expr~Permutations~{1}


{f[a], f[b], f[c]}

Using TakeList:

expr = f[a, b, c];

TakeList[expr, ConstantArray[1, Length@expr]]


{f[a], f[b], f[c]}

Other thoughts:

TakeList[expr, {1, 2}]


{f[a], f[b, c]}

• The one with TakeList is not correct. Commented Feb 15 at 11:56
• Why so, may I ask? @azerbajdzan
– Syed
Commented Feb 15 at 12:12
• Your output is {f[a], f[b, c]} not {f[a], f[b], f[c]}. Easy to overlook I guess... Commented Feb 15 at 12:13
• Read the post from the beginning, please. The second one is listed under Other thoughts`. @azerbajdzan
– Syed
Commented Feb 15 at 12:14