Why Arr.RemoveAt does not meet expectations Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Why Arr.RemoveAt does not meet expectations

31 Jul 2021, 04:50

I use deepl to translate the following

I have a script that iterates through all the files and saves them to a list
The next time it runs, it reads the list as an array
and then determine if the files exist in turn
If it doesn't exist, remove the current item and save it as a list
However, some problems arise in this step
It only deletes a portion of it each time it starts


1,Loop files to arr

Code: Select all

FileEncoding "UTF-8"
Loop files "D:\1\2\*.*", "R"
	FileAppend A_LoopFileFullPath "`r", "1.txt"
give me 708 line (707 files + 1 blank line)

2,then i rename "D:\1\2\" to "D:\1\3\"
and run that

Code: Select all

FileEncoding "UTF-8"
indexArr := StrSplit(FileRead("1.txt"), "`r")
for i in indexArr
	If ! FileExist(i)
		indexArr.RemoveAt(A_Index)
msgbox indexArr.Length
The result should be empty
But it gives 354 each time
Why

1.gif
1.gif (947.67 KiB) Viewed 1033 times
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why Arr.RemoveAt does not meet expectations

31 Jul 2021, 05:13

don't mutate the array while ure iterating through it
neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: Why Arr.RemoveAt does not meet expectations  Topic is solved

31 Jul 2021, 05:25

Just to expand what swagfag said, the problem is this line
indexArr.RemoveAt(A_Index)
For example if A_index = 3 and you do RemoveAt(A_Index) then all later items at index 4, 5, 6, ... are shifted to the left to index 3, 4, 5, ... . After the RemoveAt step the for loop continues to index 4. This means that the item now in index 3 (previously in index 4) never gets looped over and therefore never gets removed. The result is that half of the items remain in the array after the for loop finishes.

https://lexikos.github.io/v2/docs/objects/Array.htm#RemoveAt

One workaround is to check and remove array items in reverse order.

Code: Select all

indexArr := StrSplit(FileRead("1.txt"), "`r")
Len := indexArr.Length
Loop Len
{
	Index := Len - A_Index + 1
	If !FileExist(indexArr[Index])
		indexArr.RemoveAt(Index)
}
msgbox indexArr.Length
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: Why Arr.RemoveAt does not meet expectations

31 Jul 2021, 05:38

@neogna2

I think I get it.
When I delete an item
The total length changes

So, what is the best way to solve it?
Re-traversing every deleted one?
But that would be too slow!
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: Why Arr.RemoveAt does not meet expectations

31 Jul 2021, 05:40

@neogna2

thx very much
have a nice day bro
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why Arr.RemoveAt does not meet expectations

31 Jul 2021, 07:25

push any filenames that do exist into a new array(optionally overwrite the original array afterwards)

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Jeffmuvans, Lorence, ManualColdkey, ntepa and 40 guests