Dumb question on Iterating over Collections

  • Thread starter Thread starter User
  • Start date Start date
U

User

I know you can't modify the objects of a collection when iterating
over them. So what's the standard practice for deleting all the items
in a collection? I've got a collection with a bunch of objects that
all have a function delete() that deletes the object and cleans up a
bunch of stuff. I want to delete all the objects in a collection:
for each x as ideletable in col
x.delete()
next

This of course doesn't work. Should I create and array, copy the
items into the array, and then iterate over the array and delete the
items?

dim ary(col.length) as ideletable
dim i as integer = 0

for each x as ideletable in col
ary(i) = x
i += 1
next

for i as integer = 0 to ary.length()
ctype(ary(i),ideletable).delete()
next

This methods works, but is the best way of doing this?


k.
 
Does deleting the object remove it from the collection as well?

In any case, I would recommend using a for loop instead, and having the
variable count down, instead of up. That way, you start deleting at the end
of the collection, and finish at the beginning, and you never change the
indices of the items left after each deletion. You also don't need to worry
about the enumerator issue, as far as modifying the collection while
enumerating through it.
 
I don't think this would work. When you remove the 0'th element, the
element at position 1, becomes the element at position 0. So the next time,
you remove the element at position 1, when you should have removed it at 0,
to get the next one. Eventually this will get you past the end of the
collection, as it is getting smaller every time.

What would work is counting backwards, or remove the element at position 0,
n times, where n is the size of the collection.
 
You could also add a collection.clear method within your collection
and then implement the other posters suggestions within that. It would
make things cleaner.

As already pointed out, you cant change the collection with a

for..each

loop but you can with a

for i= 0 to x loop.

hth

Richard
 
K.
In addition to the descending For loop that Marina identified, I will
sometimes use a Do While loop removing the 0th element

Do While col.Count > 0
col(0).Delete()
Loop

Depending on the type of collection (an ArrayList as opposed to a
LinkedList), Marina's for loop will provide better performance, as the
ArrayList.Remove will shift all the entries down one each time you remove an
element. Hence starting at the end will not cause anything to shift...

Hope this helps
Jay
 
Jay B. Harlow said:
K.
In addition to the descending For loop that Marina identified, I will
sometimes use a Do While loop removing the 0th element

Do While col.Count > 0
col(0).Delete()
Loop

Depending on the type of collection (an ArrayList as opposed to a
LinkedList), Marina's for loop will provide better performance, as the
ArrayList.Remove will shift all the entries down one each time you remove an
element. Hence starting at the end will not cause anything to shift...

Hope this helps
Jay

This solution works for the simple collections. Unfortunatly I didn't
mention that the collections aren't always simple collection objects.
In some cases they're HashTables in which case I can't use the index
to interate.

k.
 
k,
Ah! There's the rub!

If you have a HashTable or other dictionary type collection, I would
recommend a variation, create a copy of the keys collection or a copy of the
collection itself, then delete from this copy.

Dim keys(col.Keys.Count - 1) As Object
col.Keys.CopyTo(keys, 0)

For Each key As Object In keys
DIrectCast(col(key), ideletable).delete()
Next


Dim values(col.Values.Count - 1) As Object
col.Values.CopyTo(values, 0)

For Each value As ideletable In values
value.delete()
Next

Note that (most) collections have a CopyTo method that will copy the
elements to an array for you, you don't need to manually copy each element
as your original post showed. Also I would use CopyTo from the
HashTable.Keys or HashTable.Values properties instead of HashTable.CopyTo as
HashTable.CopyTo will return an array of DictionaryEntry objects, instead of
an array of just key values or just value values...

Unfortunately the HashTable.Keys collection does not have an indexer (Item
property) defined, so you can not (easily) use the loops that were earlier
identified...

Hope this helps
Jay

User said:
"Jay B. Harlow [MVP - Outlook]" <[email protected]> wrote in message
K.
In addition to the descending For loop that Marina identified, I will
sometimes use a Do While loop removing the 0th element

Do While col.Count > 0
col(0).Delete()
Loop

Depending on the type of collection (an ArrayList as opposed to a
LinkedList), Marina's for loop will provide better performance, as the
ArrayList.Remove will shift all the entries down one each time you remove an
element. Hence starting at the end will not cause anything to shift...

Hope this helps
Jay

This solution works for the simple collections. Unfortunatly I didn't
mention that the collections aren't always simple collection objects.
In some cases they're HashTables in which case I can't use the index
to interate.

k.
 
Back
Top