# Exclude elements from mapping

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] :=
Module[
{elementList := Range[1, dim],
collectionList := {},
v = {}},
If[collectionList = Union[collectionList, v];
MemberQ[collectionList, #],
Unevaluated[Sequence[]],
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 ;)

• MapAt[f, {1, 2, 3, 4, 5}, {{2}, {5}}] ({1, f[2], 3, 4, f[5]}) ?? Feb 5, 2015 at 13:33
• I'm sorry. I have edited the question. Please inform me, if it is still unclear.
– Fred
Feb 5, 2015 at 14:47
• 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? Feb 5, 2015 at 16:51
• 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)
– Fred
Feb 13, 2015 at 14:18

## 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];
collectionList]


(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]]

• That appears to be about what I had in mind. Bu I see, I had to show an actual example^^ Nevertheless, thank you! :)
– Fred
Feb 5, 2015 at 14:51
• (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! :)
– Fred
Feb 13, 2015 at 14:27
• @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. Feb 13, 2015 at 14:39
Take[Range[50],25]
`

???????????????????????????????