# What is the way to get updated position in a list after dropping elements?

Suppose I have a function cyclePart which has a definition for the case

cyclePart[list_->{},n_,Δn_,cycle_:True]:=...


But for example in the algorithm, if it encounters a case like

cyclePart[{a,b,c,d,e,f,g,h,i,j}->{b,d,i,j},5,2,True]


I want it to transform it into the previous form so its base definition can be applied. In this case, the number 5 is referring to the position in the original list and the list to the right of the arrow tells it to drop these elements.

cyclePart[list_->drop_,n_,Δn_,cycle_:True]:=
cyclePart[Complement[list,drop]->{},...updated n...,Δn,cycle]


But how to transform n here? Is there a builtin function that can get an updated position after element drops? Note in the example, the updated list's position 3 refers to position 5 since two elements {b,d} to the left of position 5 are being removed so position 5 moves down to position 3.

As seen in the comment of @kglr Complement[list, drop] should be changed to DeleteCases[list, Alternatives @@ drop] since the former is a set drop which means it removes duplicates and sorts the list in addition to the drop. I incorrectly used Complement[list, drop] but meant the actions of DeleteCases[list, Alternatives @@ drop].

• cyclePart[list_ -> drop_, n_, \[CapitalDelta]n_, cycle_: True] := Module[{newlist = DeleteCases[list, Alternatives @@ drop]}, cyclePart[newlist -> {}, Position[newlist, list[[n]]], \[CapitalDelta]n, cycle]]?
– kglr
Feb 28, 2020 at 18:47
• ...or cyclePart[list_ -> drop_, n_, \[CapitalDelta]n_, cycle_: True] := Module[{newlist = DeleteCases[list, Alternatives @@ drop]}, cyclePart[newlist -> {}, PositionIndex[newlist][list[[n]]], \[CapitalDelta]n, cycle]]?
– kglr
Feb 28, 2020 at 18:49
• @kglr incorrect behaviour for cyclePart[{e,b,c,d,e,f,g,h,i,e}->{b,d,i,j},5,2,True] Feb 28, 2020 at 18:59
• Is there a way to look at the positions directly rather than looking at positions through the values of elements. Which is causing extra matching to occur. Feb 28, 2020 at 19:04
• One dirty trick might be to do a ReplacePart on the original list to differentiate the element first then use this trick but that doesn't seem like a professional way of doing it. Is there a function that can target positions directly? Feb 28, 2020 at 19:15

You may use Position.

With the partial definition for cyclePart.

ClearAll[cyclePart]
cyclePart[list_ -> {}, n_, Δn_, cycle_ : True] := {list, {}, n, Δn, cycle}

cyclePart[list_ -> drop_, n_, Δn_, cycle_ : True] :=
With[{c = Complement[list, drop]},
cyclePart[
c -> {},
Position[c, list[[n]]][[1, 1]],
Δn,
cycle
]
]


Then

cyclePart[{a, b, c, d, e, f, g, h, i, j} -> {b, d, i, j}, 5, 2, True]

{{a, c, e, f, g, h}, {}, 3, 2, True}

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 5, 2, True]

{{c, e, f, g, h}, {}, 2, 2, True}

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 8, 2, True]

{{c, e, f, g, h}, {}, 5, 2, True}


Hope this helps.

ClearAll[cyclePart]
cyclePart[list_ -> {}, n_, Δn_, cycle_: True] := foo[list -> {}, n, Δn, cycle]

cyclePart[list_ -> drop_, n_, Δn_, cycle_: True] := Module[{newlist =
DeleteCases[list, Alternatives @@ drop]},
cyclePart[newlist -> {}, n - Count[list[[;; n]], Alternatives @@ drop], Δn, cycle]]


Examples:

cyclePart[{a, b, c, d, e, f, g, h, i, j} -> {b, d, i, j}, 5, 2, True]


foo[{a, c, e, f, g, h} -> {}, 3, 2, True]

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 5, 2, True]


foo[{e, c, e, f, g, h, e} -> {}, 3, 2, True]

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 6, 2, True]


foo[{e, c, e, f, g, h, e} -> {}, 4, 2, True]