On Wed, Mar 19, 2008 at 10:37 AM, Jim Lucas <lists@xxxxxxxxx> wrote: > I would be interested in your examples. From what you described, I can't > see in > my head how it all goes together. > there was one caveat; i had to introduce a keyVal() instance method so client code can get the object that is the current array 'key' because internally it is the hash from spl_object_hash(), which is a string. using this hash cut down on a number of loops that were in the old implementation so i suspect this one is a little faster to boot. <?php class ObjectArray implements ArrayAccess, Countable, Iterator{ private $offsets = array(); // for optimizing iterator implementation private $indexes = array(); // array of object hashes private $values = array(); // array of mixed values private $curOffset = ''; private $curOffsetNum = -1; private $totalElements = 0; /// Countable interface public function count() { return $this->totalElements; } /** * a function to grab the actual value of the key, * if needed */ public function keyVal($key=null) { if(!is_null($key)) { return $this->indexes[$key]; } else { return $this->indexes[$this->key()]; } } /// ArrayAccess interface public function offsetExists($offset) { $offsetExists = false; $hash = spl_object_hash($offset); if(isset($this->indexes[$hash]) && isset($this->values[$hash])) { $offsetExists = true; $this->curOffset = $hash; } return $offsetExists; } public function offsetGet($offset) { if($this->offsetExists($offset)) { return $this->values[$this->curOffset]; } } /** * @note at this point it is assumed that $offset is an object */ public function offsetSet($offset, $value) { if(!$this->offsetExists($offset)) { // grab index of offset /// set value of offset for first time $hash = spl_object_hash($offset); $this->indexes[$hash] = $offset; $this->values[$hash] = $value; $this->offsets[] = $hash; $this->totalElements++; } else { /// update value of offset $this->values[$this->curOffset] = $value; } } public function offsetUnset($offset) { if($this->offsetExists($offset)) { unset($this->indexes[$this->curOffset]); unset($this->values[$this->curOffset]); $this->totalElements--; } } /// Iterator interface public function current() { return $this->values[$this->key()]; } public function key() { return $this->offsets[$this->curOffsetNum]; } public function next() { $this->curOffsetNum++; } public function rewind() { if($this->totalElements > 0) { $this->curOffsetNum = 0; } else { $this->curOffsetNum = -1; } } public function valid() { $isValid = false; if(isset($this->indexes[$this->offsets[$this->curOffsetNum]]) && isset($this->values[$this->key()])) { $isValid = true; } return $isValid; } } $objArr = new ObjectArray(); /// make $a & $c the same so == comparison should succeed $a = new StdClass(); $b = new StdClass(); $b->a = 'spl is the shit ;)'; $c = new stdClass(); // test putting a value in w/ object as index $objArr[$a] = 5; echo $objArr[$a] . PHP_EOL; // test changing the value $objArr[$a] = 6; echo $objArr[$a] . PHP_EOL; // note we can put in objs that pass == test, because internally // we use === $objArr[$c] = 7; echo 'count: ' . count($objArr) . PHP_EOL; $objArr[$b] = 8; echo 'count: ' . count($objArr) . PHP_EOL; var_dump($objArr[$a] == $objArr[$b]); // false var_dump($objArr[$a] == $objArr[$c]); // false /// now working thanks to spl_object_hash() foreach($objArr as $key => $val) { if($a === $objArr->keyVal()) { echo "keyFound: {$objArr[$a]}" . PHP_EOL; break; } } ?> -nathan