Removing entries from AAs

2011-08-19 Thread useo6
Hi,

I've create a little example of my problem:

module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); }
}

return 0;

}

When I run this small example-app, I get an Access Violation. When
I insert a break into my foreach-loop like:

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); break; }
}

it works, but this means, I leave the foreach-loop. What I'm doing
wrong by using the foreach-block?

Thanks for any help!


Re: Removing entries from AAs

2011-08-19 Thread Timon Gehr

On 08/19/2011 02:01 PM, useo6 wrote:

Hi,

I've create a little example of my problem:

module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); }
}

return 0;

}

When I run this small example-app, I get an Access Violation. When
I insert a break into my foreach-loop like:

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); break; }
}

it works, but this means, I leave the foreach-loop. What I'm doing
wrong by using the foreach-block?

Thanks for any help!


The problem is that you change the AA while iterating over it. You could 
eg iterate over it and save all keys you want to remove into an array 
and then iterate over the array to remove the keys from the AA.


This works:


module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

hash_t[] toRemove;

foreach (c; exp) {
if (c.mi == 2) { toRemove~=c.toHash(); }
}
foreach (h; toRemove) {
exp.remove(h);
}

return 0;

}





Re: Removing entries from AAs

2011-08-19 Thread useo6
== Auszug aus Timon Gehr (timon.g...@gmx.ch)'s Artikel
 On 08/19/2011 02:01 PM, useo6 wrote:
  Hi,
 
  I've create a little example of my problem:
 
  module example;
 
  class ExampleClass {
 
  public {
 
  int mi;
 
  this(int i) {
  mi = i;
  }
 
  }
 
  }
 
  int main(string[] args) {
 
  ExampleClass[hash_t] exp;
 
  ExampleClass cex = new ExampleClass(1);
  exp[cex.toHash()] = cex;
 
  cex = new ExampleClass(2);
  exp[cex.toHash()] = cex;
 
  cex = new ExampleClass(3);
  exp[cex.toHash()] = cex;
 
  foreach (ExampleClass c; exp) {
  if (c.mi == 2) {exp.remove(c.toHash()); }
  }
 
  return 0;
 
  }
 
  When I run this small example-app, I get an Access Violation.
When
  I insert a break into my foreach-loop like:
 
  foreach (ExampleClass c; exp) {
  if (c.mi == 2) {exp.remove(c.toHash()); break; }
  }
 
  it works, but this means, I leave the foreach-loop. What I'm doing
  wrong by using the foreach-block?
 
  Thanks for any help!
 The problem is that you change the AA while iterating over it. You
could
 eg iterate over it and save all keys you want to remove into an
array
 and then iterate over the array to remove the keys from the AA.
 This works:
 module example;
 class ExampleClass {
   public {
   int mi;
   this(int i) {
   mi = i;
   }
   }
 }
 int main(string[] args) {
   ExampleClass[hash_t] exp;
   ExampleClass cex = new ExampleClass(1);
   exp[cex.toHash()] = cex;
   cex = new ExampleClass(2);
   exp[cex.toHash()] = cex;
   cex = new ExampleClass(3);
   exp[cex.toHash()] = cex;
   hash_t[] toRemove;
   foreach (c; exp) {
   if (c.mi == 2) { toRemove~=c.toHash(); }
   }
   foreach (h; toRemove) {
   exp.remove(h);
   }
   return 0;
 }

I already thought about that situation, but some explained the
removing/clearing of an array by iterate over each element and remove
it from the AA. I just solved the problem by using the HashSet-class
from the dcollection's.