Sign in to follow this  
Followers 0
lonewolf217

deleting items from object while processing each item

9 posts in this topic

Forgive the title, but i wasn't sure how to explain my problem simply.

Basically I have an object containing a list of many items. I am parsing it like

for $item in $object

;do something

;if some condition matches, delete item

next

the problem that i am having with this is probably a fairly obvious one, but the solution escapes me at the moment.

It seems that when I delete an item in the list, it will shift the rest of the items in the $object up on position, so when the Next condition is hit, it is actually skipping over one object to get to the next one in the list.

for example

$object is an array of numbers [1,2,3,4,5,6,7,8,9,10]

in my oversimplified code

for $item in $object

if $item == 2 then delete $item

next

the way this seems to work is that it will process $item == 2, then delete "2". then the next number it will process is actually 4

Is this actually the way it is behaving or could I have another bug in my code?

Share this post


Link to post
Share on other sites

Depends on what kind of object you're using. If its just an array, then you can use a For..To loop instead like so:

For $i=0 To Ubound($aMyarray)-1
     If $aMyarray[$i] = 2 Then
          _ArrayDelete($aMyarray, $i)
          $i -= 1
     EndIf
Next

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

unfortunetly the size of the array is dynamic, and I suppose that im not actually using an array at all, I am using an object with a lot of members

the jist of what I am doing is processing an Exchange Mailbox, and the object I am working on is the list of all messages in the folder

for each folder/subfolder I process each message and check for a certain message class, if it exists I delete the message

What I am seeing in my code right now is that if I have multiple of the same message class in a row it is skipping them

I had tried hard coding the value of the count for each folder but that got really messy and I was hoping to avoid it

Edited by lonewolf217

Share this post


Link to post
Share on other sites

is there a way that I can get the numeric value of the position in the object I am in ? perhaps then i can lower the value by 1 when i delete a message

Share this post


Link to post
Share on other sites

To do it simpler than how it is working out now, instead of deleting them with this run, just append a list of the names of the messages to delete, preferably to an array. Then, loop through the array, deleting matching messages.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Ive tried the latest suggestion by saving a list of entry ids in an array and then going back and trying to load and delete them later but it isn't working out yet so I am back to the original problem.

here is a code snippet of one of my functions if someone can take a look and possibly let me know my mistake

CODE

Func processFolders($folders)

for $folder in $folders

If $folder.Items.count <> 0 Then

for $message in $folder.Items

If $message.MessageClass == "IPM.Note.Stub" Then

$message.Delete

EndIf

Next

EndIf

If $folder.Folders.count <> 0 Then

processFolders($folder.Folders)

EndIf

Next

EndFunc

I am using the Redemption libraries for this code. $folder is the folder object, $Folder.Items is an object containing all the messages in the folder.

I am running this over and over and cannot figure out why it is skipping messages. If i have 10 messages in my Inbox that apply to the MessageClass rule, for some reason only 5 of them are getting deleted. Any help is appreciated.

Edit: sorry about the code snippet formatting, can't figure out how to get the indentation to work

Edited by lonewolf217

Share this post


Link to post
Share on other sites

Try this:

#include <Array.au3>

Func processFolders($folders)
    Local $aDeleteFolders[1] = [0]
    for $folder in $folders
        If $folder.Items.count <> 0 Then
            for $message in $folder.Items
                If $message.MessageClass == "IPM.Note.Stub" Then
                    _ArrayAdd($aDeleteFolders, $message)
                    $aDeleteFolders[0] += 1
                EndIf
            Next
        EndIf
        For $i=1 To $aDeleteFolders[0]
            For $message In $folder.Items
                If $message = $aDeleteFolders[$i] Then
                    $message.Delete
                    ExitLoop
                EndIf
            Next
        Next
        ReDim $aDeleteFolders[1]
        $aDeleteFolders[0] = 0
        If $folder.Folders.count <> 0 Then
            processFolders($folder.Folders)
        EndIf
    Next
EndFunc

Share this post


Link to post
Share on other sites

I finally found some information on google and it does seem that since i am modifying the number of items in the object it will screw up the count. Once i changed my for loop to this

for $i = $folder.Items.count To 1 Step -1

it works just fine.

Thanks for the help though!

Share this post


Link to post
Share on other sites

Check out the _Array UDF, in the UDF help file in your main AutoIt folder. That should give you all the functionality you need.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0