Reorganizing children of an instance of SplObjectStorage

I have an instance of SplObjectStorage that stores the objects of the elements that will be displayed in the container. I would like to be able to effectively add and remove objects from any random position in the store.

Example:

<?php $store = new SplObjectStorageWrapper; $obj1 = new Obj; $obj2 = new Obj; $obj3 = new Obj; $store->attach($obj1); $store->attach($obj2); $store->insertAtIndex($obj3, 1); //Storage should now be organized as $obj1, $obj3, $obj2 

How can I apply the insertAtIndex method? Should I use LimitIterator to disconnect and reconnect children after a certain position? Using array-based object storage was much slower than an instance of SplObjectStorage .

Other methods that I would like to implement include removeAtIndex(integer) and indexOf(object)

+4
source share
1 answer

It turns out the easiest (and apparently the most efficient) way to do this is to extend SplObjectStorage and use LimitIterator . Sample code below:

 <?php /** * Extends the SplObjectStorage class to provide index functions */ class ObjectStorage extends SplObjectStorage { /** * Returns the index of a given object, or false if not found * @param object $object */ function indexOf($object){ if(!$this->contains($object)) return false; foreach($this as $index => $obj) if($obj === $object) return $index; } /** * Returns the object at the given index */ function itemAtIndex($index){ $it = new LimitIterator($this, $index, 1); foreach($it as $obj) return $obj; } /** * Returns the sequence of objects as specified by the offset and length * @param int $offset * @param int $length */ function slice($offset, $length){ $out = array(); $it = new LimitIterator($this, $offset, $length); foreach($it as $obj) $out[] = $obj; return $out; } /** * Inserts an object (or an array of objects) at a certain point * @param mixed $object A single object or an array of objects * @param integer $index */ function insertAt($object, $index){ if(!is_array($object)) $object = array($object); //Check to ensure that objects don't already exist in the collection foreach($object as $k => $obj): if($this->contains($obj)) unset($object[$k]); endforeach; //Do we have any objects left? if(!$object) return; //Detach any objects at or past this index $remaining = array(); if($index < $this->count()): $remaining = $this->slice($index, $this->count() - $index); foreach($remaining as $obj) $this->detach($obj); endif; //Add the new objects we're splicing in foreach($object as $obj) $this->attach($obj); //Attach the objects we previously detached foreach($remaining as $obj) $this->attach($obj); } /** * Removes the object at the given index * @param integer $index */ function removeAt($index){ $this->detach($this->itemAtIndex($index)); } } 
+3
source

Source: https://habr.com/ru/post/1389334/


All Articles