View mode: basic / threaded / horizontal-split · Log in · Help
February 17, 2012
Removing items from an Array
Hello everybody.
Once again I have a little question, this time about removing 
items from an assoc array in a foreach.

Why does the following code:
http://pastebin.com/65P9WDNS
Result in this output:
http://pastebin.com/4FzEE1zi

It seems rather strange to me. I'd expect the foreach_reverse to 
go over the array from the end to the beginning, and when I 
remove stuff from it, it shouldn't be a problem. But apparently 
it is.

Mars
February 17, 2012
Re: Removing items from an Array
On Friday, February 17, 2012 11:00:36 Mars wrote:
> Hello everybody.
> Once again I have a little question, this time about removing
> items from an assoc array in a foreach.
> 
> Why does the following code:
> http://pastebin.com/65P9WDNS
> Result in this output:
> http://pastebin.com/4FzEE1zi
> 
> It seems rather strange to me. I'd expect the foreach_reverse to
> go over the array from the end to the beginning, and when I
> remove stuff from it, it shouldn't be a problem. But apparently
> it is.

I don't believe that removing elements from an AA while iterating over it is 
safe.

- Jonathan M Davis
February 17, 2012
Re: Removing items from an Array
On Friday, 17 February 2012 at 10:13:00 UTC, Jonathan M Davis 
wrote:
> I don't believe that removing elements from an AA while 
> iterating over it is safe.
>
> - Jonathan M Davis

Well, no. But from my experience it's okay from bottom to top... 
at least in other languages.
What would be the alternative? Maybe build a new array while 
iterating, and set it after the loop?
February 17, 2012
Re: Removing items from an Array
foreach_reverse isn't going to help you much since AA's do not save
the order of the keys. A quick workaround:
http://pastebin.com/KkECqwUU

Others probably know efficient ways to do this.
February 17, 2012
Re: Removing items from an Array
Usually in other languages iterators are safe.

Il giorno ven, 17/02/2012 alle 11.35 +0100, Mars ha scritto:

> On Friday, 17 February 2012 at 10:13:00 UTC, Jonathan M Davis 
> wrote:
> > I don't believe that removing elements from an AA while 
> > iterating over it is safe.
> >
> > - Jonathan M Davis
> 
> Well, no. But from my experience it's okay from bottom to top... 
> at least in other languages.
> What would be the alternative? Maybe build a new array while 
> iterating, and set it after the loop?
February 17, 2012
Re: Removing items from an Array
AAs don't keep the key order, so when you delete something out of it,
what ever system iterates to the next pointer gets confused. Its
generally a bad idea to modify an array as you loop through it.

--
James Miller
February 17, 2012
Re: Removing items from an Array
On Friday, 17 February 2012 at 13:33:25 UTC, James Miller wrote:
> AAs don't keep the key order, so when you delete something out 
> of it,
> what ever system iterates to the next pointer gets confused. Its
> generally a bad idea to modify an array as you loop through it.
>
> --
> James Miller

Too bad. So, what would be the correct way to do this? I mean... 
it's not that uncommon, to have this problem.
Are creating a new array while iterating over it, or creating a 
list of elements to remove, and removing them afterwards, the 
only ways to do this?
February 17, 2012
Re: Removing items from an Array
On Friday, February 17, 2012 14:44:42 Mars wrote:
> On Friday, 17 February 2012 at 13:33:25 UTC, James Miller wrote:
> > AAs don't keep the key order, so when you delete something out
> > of it,
> > what ever system iterates to the next pointer gets confused. Its
> > generally a bad idea to modify an array as you loop through it.
> > 
> > --
> > James Miller
> 
> Too bad. So, what would be the correct way to do this? I mean...
> it's not that uncommon, to have this problem.
> Are creating a new array while iterating over it, or creating a
> list of elements to remove, and removing them afterwards, the
> only ways to do this?

That's the way that I'd do it.

- Jonathan M Davis
February 17, 2012
Re: Removing items from an Array
On Fri, 17 Feb 2012 08:44:42 -0500, Mars <-@-.-> wrote:

> On Friday, 17 February 2012 at 13:33:25 UTC, James Miller wrote:
>> AAs don't keep the key order, so when you delete something out of it,
>> what ever system iterates to the next pointer gets confused. Its
>> generally a bad idea to modify an array as you loop through it.
>>
>> --
>> James Miller
>
> Too bad. So, what would be the correct way to do this? I mean... it's  
> not that uncommon, to have this problem.
> Are creating a new array while iterating over it, or creating a list of  
> elements to remove, and removing them afterwards, the only ways to do  
> this?

If you are interested in an alternative implementation that does allow  
this, see here:

www.dsource.org/projects/dcollections

One of the features is "Removal while traversing."

In particular pay attention to the purge and keyPurge functions of the  
HashMap class and its usage.

The docs are woefully underdeveloped, but you can see how its used here:

http://www.dsource.org/projects/dcollections/browser/branches/d2/concepts.txt#L81

-Steve
February 21, 2012
Re: Removing items from an Array
On 18 February 2012 05:30, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> On Friday, February 17, 2012 14:44:42 Mars wrote:
>> On Friday, 17 February 2012 at 13:33:25 UTC, James Miller wrote:
>> > AAs don't keep the key order, so when you delete something out
>> > of it,
>> > what ever system iterates to the next pointer gets confused. Its
>> > generally a bad idea to modify an array as you loop through it.
>> >
>> > --
>> > James Miller
>>
>> Too bad. So, what would be the correct way to do this? I mean...
>> it's not that uncommon, to have this problem.
>> Are creating a new array while iterating over it, or creating a
>> list of elements to remove, and removing them afterwards, the
>> only ways to do this?
>
> That's the way that I'd do it.
>
> - Jonathan M Davis

Pretty much. To expand on Jonathan's answer, the problem with
iterating and deleting is that the conditions when the loop started
are not the same as the conditions at the middle or end. With a
fixed-size array, you can do it safely assuming you write the proper
conditions, and you don't accidentally convert it to a slice.
With removal, taking a small memory hit to create a new array tends to
be worth it, since you can reclaim the memory from the old one (which
is presumably bigger). This is the kind of condition that memory
"scratch" spaces are advocated for (often used in game dev, due to
massive data processing requirements at speed). However, I don't
suggest implementing said scratch space in D, since the GC pretty much
does this anyway.
Top | Discussion index | About this forum | D home