Jump to page: 1 2
Thread overview
AA.remove in foreach && AA = new vs cleaning
Oct 22, 2009
Saaa
Oct 22, 2009
Saaa
Oct 22, 2009
Saaa
Oct 22, 2009
Saaa
Oct 22, 2009
Saaa
Oct 22, 2009
Rainer Deyke
Oct 22, 2009
Saaa
October 22, 2009
Is there anything with removing the current key in a foreach?

foreach (K k, ; aa)
{
  ..
  aa.remove(k);
}

What if it isn't the current key?
If the iteration is generated on the fly it shouldn't be a problem, right?

&&

Is it better to new an AA or empty(.remove) it on the fly if you loop over
all the keys anyways?
That is, I need an similar empty AA the next iteration :)
Removing every element takes of course as many operations as keys, but
filling the array won't take
as many memory allocations, as the gc doesn't return the key allocations. Am
I making any sense here? :D


October 22, 2009
On Wed, 21 Oct 2009 23:06:47 -0400, Saaa <empty@needmail.com> wrote:

> Is there anything with removing the current key in a foreach?
>
> foreach (K k, ; aa)
> {
>   ..
>   aa.remove(k);
> }
>

Yes, behavior is undefined.

from http://digitalmars.com/d/2.0/statement.html#ForeachStatement :

"The aggregate must be loop invariant, meaning that elements to the aggregate cannot be added or removed from it in the [loop body]"

I have gotten around this in dcollections by removing elements outside the loop body.  See for example the keypurge function of HashMap (http://www.dsource.org/projects/dcollections/docs/current/dcollections.HashMap.html)

-Steve
October 22, 2009
Steven Schveighoffer wrote:
> Yes, behavior is undefined.
>
> from http://digitalmars.com/d/2.0/statement.html#ForeachStatement :
>
> "The aggregate must be loop invariant, meaning that elements to the aggregate cannot be added or removed from it in the [loop body]"
I suspect removing the current key isn't a problem in the current
implementation;
Been using it quite a lot without any problems :)
But I've changed everything to new the array afterwards as I deleted all the
keys anyways.
>
> I have gotten around this in dcollections by removing elements outside the loop body.  See for example the keypurge function of HashMap (http://www.dsource.org/projects/dcollections/docs/current/dcollections.HashMap.html)
Do you add the ones to be deleted to a dynamic array or do you loop over all elements afterwards? I expect the first :)




October 22, 2009
On Thu, 22 Oct 2009 00:45:36 -0400, Saaa <empty@needmail.com> wrote:

> Steven Schveighoffer wrote:
>> Yes, behavior is undefined.
>>
>> from http://digitalmars.com/d/2.0/statement.html#ForeachStatement :
>>
>> "The aggregate must be loop invariant, meaning that elements to the
>> aggregate cannot be added or removed from it in the [loop body]"
> I suspect removing the current key isn't a problem in the current
> implementation;
> Been using it quite a lot without any problems :)

It may well sometimes work, but it's not defined to work.  I've seen instances where it caused problems (i.e. segfaults).  You may just not have hit that threshold.

> But I've changed everything to new the array afterwards as I deleted all the
> keys anyways.

Not sure what you mean here.

>>
>> I have gotten around this in dcollections by removing elements outside the
>> loop body.  See for example the keypurge function of HashMap
>> (http://www.dsource.org/projects/dcollections/docs/current/dcollections.HashMap.html)
> Do you add the ones to be deleted to a dynamic array or do you loop
> over all elements afterwards? I expect the first :)

I delete them as they are requested to be deleted.  Since the deletion is done by the opApply function, it has knowledge of when it is ok to delete the element, and can save off any necessary structural information needed to get to the next element.

It makes for an efficient method to traverse and remove in one pass.

-Steve
October 22, 2009
Steven Schveighoffer wrote

>> But I've changed everything to `new` the array afterwards as I deleted
>> all  the
>> keys anyways.
>
> Not sure what you mean here.

foreach (K k, ; aa)
{
  ..
  //aa.remove(k);
}
aa = new int[char];

>
>>>
>>> I have gotten around this in dcollections by removing elements outside
>>> the
>>> loop body.  See for example the keypurge function of HashMap
>>> (http://www.dsource.org/projects/dcollections/docs/current/dcollections.HashMap.html)
>> Do you add the ones to be deleted to a dynamic array or do you loop over all elements afterwards? I expect the first :)
>
> I delete them as they are requested to be deleted.  Since the deletion is done by the opApply function, it has knowledge of when it is ok to delete the element, and can save off any necessary structural information needed to get to the next element.
How is this `outside the loop body`?
Should I read it as `after the loop body`?

>
> It makes for an efficient method to traverse and remove in one pass.
>
> -Steve


October 22, 2009
Saaa wrote:
> Steven Schveighoffer wrote
>
>>> But I've changed everything to `new` the array afterwards as I deleted
>>> all  the
>>> keys anyways.
>>
>> Not sure what you mean here.
>
> foreach (K k, ; aa)
> {
>  ..
>  //aa.remove(k);
> }
> aa = new int[char];

Error: new can only create structs, dynamic arrays or class objects

So, what is the fastest way to clean an AA?


October 22, 2009
> So, what is the fastest way to clean an AA?
dsource tutorials to the rescue :  loop over all keys and remove. Now I understand the AA discussion on .D :)


October 22, 2009
Saaa wrote:
> So, what is the fastest way to clean an AA?

int[char] tmp;
aa = tmp;


-- 
Rainer Deyke - rainerd@eldwood.com
October 22, 2009
On Thu, 22 Oct 2009 02:59:13 -0400, Saaa <empty@needmail.com> wrote:

> Saaa wrote:
>> Steven Schveighoffer wrote
>>
>>>> But I've changed everything to `new` the array afterwards as I deleted
>>>> all  the
>>>> keys anyways.
>>>
>>> Not sure what you mean here.
>>
>> foreach (K k, ; aa)
>> {
>>  ..
>>  //aa.remove(k);
>> }
>> aa = new int[char];
>
> Error: new can only create structs, dynamic arrays or class objects
>
> So, what is the fastest way to clean an AA?

aa = null;

However, if you have multiple copies of the AA, this does not clear out the data.  It merely resets the AA reference.

I'd not trust your code because it's undefined behavior.  If you want to remove all the elements individually, copy the keys to an array, then iterate over the array removing each element.

Or use a real collection class, such as Tango's or dcollections' and use the clear() method :)

-Steve
October 22, 2009
Steven Schveighoffer wrote:
>> So, what is the fastest way to clean an AA?
>
> aa = null;
:(
>
> However, if you have multiple copies of the AA, this does not clear out the data.  It merely resets the AA reference.
>
> I'd not trust your code
:)
> because it's undefined behavior.  If you want to  remove all the elements individually, copy the keys to an array, then  iterate over the array removing each element.
This is what the dsource example does, it loops over a copy of all the keys
:)
foreach(K key; aa.keys)
 aa.remove(key);

>
> Or use a real collection class, such as Tango's or dcollections' and use the clear() method :)
>
> -Steve
As nulling is all it takes I don't think it's that much faster :)


« First   ‹ Prev
1 2