I have had this problem way too often and still have not found a solution, yet. One acually used code is:`

VectorQuantity[perms_List, dim_Integer] :=
  {elementList := Range[1, dim],
   collectionList := {},
   v = {}},
  If[collectionList = Union[collectionList, v]; 
     MemberQ[collectionList, #],
     v = PermutationReplace[#, perms]] & /@ elementList]

perms is a list of cycles. During the mapping over elementList I find elements over which I do not want to map anymore. Right now, they are put into a list, and I use If and MemberQ. I know that there are more issues with the code like the ; within the condition, but those do not matter to me, right now. What I am asking for is whether there is a good way to control the part behind the /@

I apologize for unclearness in the unedited question. I am rather new to Mathematica, and my English is terrible ;)

  • $\begingroup$ MapAt[f, {1, 2, 3, 4, 5}, {{2}, {5}}] ({1, f[2], 3, 4, f[5]}) ?? $\endgroup$ Feb 5, 2015 at 13:33
  • $\begingroup$ I'm sorry. I have edited the question. Please inform me, if it is still unclear. $\endgroup$
    – Fred
    Feb 5, 2015 at 14:47
  • $\begingroup$ I must admit I still have trouble understanding this. Assuming your code works as you intend what is wrong with using MemberQ and then effectively dropping the element with Unevaluated[Sequence[]]? (Which by the way you can replace with ## &[].) Conceptually how else would you do this? $\endgroup$
    – Mr.Wizard
    Feb 5, 2015 at 16:51
  • $\begingroup$ The problem here is that this code will be performed for very huge dim. But in general, I am really curious about whether there is a way to implement this more efficiently. Now, a friend of mine has replaced it with a "reap-nestwhile-saw"-function which is actually better. (I do not have the code here, right now. If you want, I can add it soon) $\endgroup$
    – Fred
    Feb 13, 2015 at 14:18

2 Answers 2


Answer rewritten after changes to question

[See the edit history for the previous version.]

As I understand the revised example code, and I'm not sure if this is correct or even if it actually has any utility, the function $f$ should be mapped such that the result $y_i = f(x_i)$ is not calculated if the argument $x_i$ appears in the prior results, $y_1, y_2, ... y_{i-1}$.

I think the following is a function that generalises this:

strangelyMap[f_, elementList_List] := Block[
  {collectionList = {f[First[elementList]]}, g},
  g[x_] := (collectionList = Join[collectionList, {f[x]}]) /; ! MemberQ[collectionList, x];
  g /@ Rest[elementList];

(Replace Join by Union if you require sorted results with no repeats.)

A somewhat contrived example:

strangelyMap[Mod[#, 10] &, Reverse[Range[20]]]

{0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}

And the way to use it with the incomplete example in the question:

strangelyMap[PermutationReplace[#, perms] &, Range[dim]]
  • $\begingroup$ That appears to be about what I had in mind. Bu I see, I had to show an actual example^^ Nevertheless, thank you! :) $\endgroup$
    – Fred
    Feb 5, 2015 at 14:51
  • $\begingroup$ (after your edit) That function does exactly what I meant. But my actual question is: Is there a more efficient way to implement strangelyMap? Still, thank you very much! :) $\endgroup$
    – Fred
    Feb 13, 2015 at 14:27
  • $\begingroup$ @Fred As you said "I have had this problem way too often" I thought a generalisation would be helpful. I'm not sure there can be a better method unless you know the results in advance. $\endgroup$ Feb 13, 2015 at 14:39



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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