2
$\begingroup$

I would like to know if there is a nice functional way to code up a MapList which applies f to each element of expr and returns a list of the results obtained.

Here is my implementation:

MapList[f_, expr_] := List @@ (MapIndexed[ReplacePart[expr, #2 -> f[#1]] &, expr])

It works in this test case:

myData = head[a, b, c, d];
MapList[f, myData]

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

But if the head has some DownValues or funny Attributes like this:

SetAttributes[head, Flat];
MapList[f, myData]

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

it gives the wrong result (because the Flat is kicking in before List @@ swaps out the head of the output).

How do I program a ListMap that is as fast and robust against possible definitions attached to head?

$\endgroup$

closed as off-topic by QuantumDot, Sektor, MarcoB, m_goldberg, Henrik Schumacher May 24 '18 at 6:12

  • The question does not concern the technical computing software Mathematica by Wolfram Research. Please see the help center to find out about the topics that can be asked here.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 6
    $\begingroup$ Something like MapAt[f,expr,#]&/@Range[Length[expr]]? $\endgroup$ – chuy May 23 '18 at 19:56
  • $\begingroup$ Yup! And also the variation Array[MapAt[f,expr,#]&,Length[expr]] works. $\endgroup$ – QuantumDot May 23 '18 at 21:19
  • 4
    $\begingroup$ I'm voting to close this question as off-topic because it is a duplicate of stackoverflow.com/questions/7944549/a-maplist-function $\endgroup$ – QuantumDot May 24 '18 at 2:16
6
$\begingroup$

A asked something not too dissimilar some years ago:

https://stackoverflow.com/questions/7944549/a-maplist-function

My implementation from the question itself:

MapList[f_, expr_, level_: 1] :=
 MapAt[f, expr, #] & /@
  Position[expr, _, level, Heads -> False]

This happens to handle your example:

myData = head[a, b, c, d];
SetAttributes[head, Flat];
MapList[f, myData]
{head[f[a], b, c, d], head[a, f[b], c, d], head[a, b, f[c], d], head[a, b, c, f[d]]}

I suspect you may find the answers I recieved of interest as well.

$\endgroup$
  • $\begingroup$ Oh, I totally missed that! Please mark my question as a duplicate. Your answer and the answers there are quite helpful. $\endgroup$ – QuantumDot May 24 '18 at 2:15

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