Question

I have an SPLObjectStorage object with a Player object as the key and score as the info associated with it. The player objects get added to the storage in order from highest to lowest score, but I'm now to a point where I need to iterate through them in reverse order.

I also need to be able to loop all the way through starting from a specified offset. I've figured this part out below, I just can't figure out a good way to reverse it first.

// $players_group = new SPLObjectStorage()
// code to add Player and Score would go here
// above lines just for example

# NEED TO REVERSE ORDER PLAYERS GROUP HERE

$infinite_it = new InfiniteIterator($players_group);
$limit_it = new LimitIterator($infinite_it, $current_offset, $players_group->count());
foreach($limit_it as $p){
    // properly outputting from offset all the way around
    // but I need it in reverse order
}

I would like to avoid having to loop through the storage object and push all of them into an array, then do array_reverse, and then finally proceed with my foreach loop.

Était-ce utile?

La solution

SplObjectStorage is a key->value store and The "key" of an element in the SplObjectStorage is in fact the hash of the object. Sorting and Reverting would require you to extend and write your own implementation but i think you should consider Using SplStack

Imagine your player class

class Player {
    private $name;
    function __construct($name) {
        $this->name = $name;
    }
    function __toString() {
        return $this->name;
    }
}

Using SplStack

$group = new SplStack();
$group->push(new Player("Z"));
$group->push(new Player("A"));
$group->push(new Player("B"));
$group->push(new Player("C"));

echo "<pre>";
$infinite_it = new InfiniteIterator($group);
$limit_it = new LimitIterator($infinite_it, 0, 3); // get frist 3
foreach ( $limit_it as $p ) {
    echo ("$p");
}

If you insist on SplObjectStorage then you can consider a custom ReverseArrayIterator

class ReverseArrayIterator extends ArrayIterator {
    public function __construct(Iterator $it) {
        parent::__construct(array_reverse(iterator_to_array($it)));
    }
}

Usage

$group = new SplObjectStorage();
$group->attach(new Player("Z"));
$group->attach(new Player("A"));
$group->attach(new Player("B"));
$group->attach(new Player("C"));

echo "<pre>";
$infinite_it = new InfiniteIterator(new ReverseArrayIterator($group));
$limit_it = new LimitIterator($infinite_it, 0, 3); // get frist 3
foreach ( $limit_it as $p ) {
    echo ("$p");
}

Both would Output

CBA //reversed 

Autres conseils

I would like to avoid having to loop through the storage object and push all of them into an array, then do array_reverse, and then finally proceed with my foreach loop.

Don't know if it is the most efficient way but as SplObjectStorage implements Iterator you can use iterator_to_array and then reverse the array :

array_reverse(iterator_to_array($players_group));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top