简体   繁体   English

反向SPLObjectStorage

[英]Reverse SPLObjectStorage

I have an SPLObjectStorage object with a Player object as the key and score as the info associated with it. 我有一个SPLObjectStorage对象,其中有一个Player对象作为键,并获得了与之关联的信息的分数。 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. 我想避免必须遍历存储对象并将它们全部推入数组,然后执行array_reverse,然后最后进行我的foreach循环。

SplObjectStorage is a key->value store and The "key" of an element in the SplObjectStorage is in fact the hash of the object. SplObjectStoragekey->value store并且SplObjectStorage元素的“键”实际上是对象的哈希。 Sorting and Reverting would require you to extend and write your own implementation but i think you should consider Using SplStack 排序和还原需要您扩展和编写自己的实现,但我认为您应该考虑使用SplStack

Imagine your player class 想象一下您的球员职业

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

Using SplStack 使用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 如果您坚持使用SplObjectStorage则可以考虑使用自定义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 

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. 我想避免必须遍历存储对象并将它们全部推入数组,然后执行array_reverse,然后最后进行我的foreach循环。

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 : 不知道这是否是最有效的方法,但是当SplObjectStorage实现Iterator时,您可以使用iterator_to_array然后反转数组:

array_reverse(iterator_to_array($players_group));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM