I'm dealing with a class that implements ArrayAccess AND Iterator (let's say $a) and, while looping through it with a foreach, I would like to remove/unset some elements (based on some if conditions).
foreach($a as $item) {
if(mustBeRemoved()) {
$a->remove($item);
}
}
Now, the problem in my implementation is that this provoke an unexpected behaviour in the foreach loop, cause it will not be aware of the changes and will keep going and stopping prematurely regardless the element removed (or added).
Is there a good/elegant way to solve this issue?
I don't have your problem when I implemented a class that implements an Iterator and ArrayAccess for testing purpose:
<?php
class a implements Iterator, ArrayAccess {
public $items = array();
private $index = 0;
public function current() {
return $this->items[$this->index];
}
public function key() {
return $this->index;
}
public function next() {
++$this->index;
}
public function rewind() {
$this->index = 0;
}
public function valid() {
return array_key_exists($this->index, $this->items);
}
public function offsetExists($offset) {
return array_key_exists($offset, $this->items);
}
public function offsetGet($offset) {
return $this->items[$offset];
}
public function offsetSet($offset, $value) {
$this->items[$offset] = $value;
}
public function offsetUnset($offset) {
unset($this->items[$offset]);
}
public function remove($item) {
foreach($this->items as $index => $itemsItem) {
if( $itemsItem == $item) {
unset($this->items[$index]);
break;
}
}
}
}
$a = new a();
array_map(array($a, 'offsetSet'), range(0, 100), range(0, 100));
foreach($a as $item) {
if( $item % 2 === 0 ) {
$a->remove($item);
}
}
var_dump($a->items);
If you implemented the iterator, change it making sure removing an item won't make the "a" instance return different items when "next" and "current" are called.
Otherwise, you can try this:
$mustBeRemoved = array();
foreach($a as $item) {
if(mustBeRemoved()) {
$mustBeRemoved []= $item;
}
}
foreach($mustBeRemoved as $item) {
$a->remove($item);
}
unset($mustBeRemoved);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With