一种用于递归迭代器的 iterator_to_array 来获取二维数组

发布于 2025-01-01 16:24:58 字数 2890 浏览 3 评论 0原文

在 PHP 中使用迭代器时,您可以使用 iterator_to_array 函数来提取迭代结果的数组。例如,假设您有以下 ArrayObject

$array_object = new ArrayObject(array(
   array('1', '2', '3', '4'),
   array('5', '6', '7', '8'),
   array('9', '10', '11', '12'),
));

如您所见,它的存储是一个二维数组。

我们可以构造一个 FilterOperator 来只接受它的第一个项目(我知道使用 LimitIterator 会更好,它只是作为示例目的):

class myFilterIterator extends FilterIterator
{
   public function accept()
   {
      return ($this->key() === 0);
   }
}

$filter_iterator = new myFilterIterator(new ArrayIterator($array_object));

现在,如果我这样做:

print_r(iterator_to_array($filter_iterator));

我获取如果我手动循环操作符可以获得的数组:

Array ( [0] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) )

但是如果我想使用 RecursiveFilterIterator ,现在该怎么办?假设我有:

class myRecursiveFilterIterator extends RecursiveFilterIterator
{
   public function accept()
   {
      return ($this->hasChildren() || $this->key() === 0);
   }
}

$recursive_filter_iterator = new myRecursiveFilterIterator(new RecursiveArrayIterator($array_object));

如您所见,这将只接受父数组中包含的每个数组的键 0。因此,如果我递归迭代它,它就会起作用:

foreach (new RecursiveIteratorIterator($recursive_filter_iterator) as $value) {
   print_r($value);
   echo '<br />';
}

结果:

1
5
9

但是,如何快速获取数组 array(array(1), array(5), array(9))

如果我这样做:

print_r(iterator_to_array($recursive_filter_iterator));

或者

print_r(iterator_to_array($recursive_filter_iterator->getInnerIterator()));

或者

$it = new RecursiveIteratorIterator($recursive_filter_iterator);
print_r(iterator_to_array($it->getInnerIterator()));

我得到整个原始数组:

Array ( [0] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) [1] => Array ( [0] => 5 [1] => 6 [2] => 7 [3] => 8 ) [2] => Array ( [0] => 9 [1] => 10 [2] => 11 [3] => 12 ) )

如果我这样做:

print_r(iterator_to_array(new RecursiveIteratorIterator($recursive_filter_iterator)));

我只得到第一项:

Array ( [0] => 9 )

如果我这样做:

print_r(iterator_to_array(new RecursiveIteratorIterator($recursive_filter_iterator->getInnerIterator())));

我得到父数组中的最后一项,但键为0:

Array ( [0] => 9 [1] => 10 [2] => 11 [3] => 12 ) 

我需要的是获取数组:

Array ( [0] => Array ( [0] => 1 ) [1] => Array ( [0] => 5 ) [2] => Array ( [0] => 9 ) ) 

我知道我可以手动循环它,但我想知道是否有直接的方法,例如在iterator_to_array中用于非递归迭代器。当然,我对 PHP 中的递归迭代器有一些不明白的地方,但它的文档在这方面确实很糟糕。

非常感谢。

when using iterators in PHP you can use iterator_to_array function to kind of extract the array resulting of iterating. For example, let's say you have following ArrayObject:

$array_object = new ArrayObject(array(
   array('1', '2', '3', '4'),
   array('5', '6', '7', '8'),
   array('9', '10', '11', '12'),
));

As you see, its storage is a bi-dimensional array.

We can crete a FilterOperator to only accept its first item (I know it would be better with LimitIterator, it's just as an example purpose):

class myFilterIterator extends FilterIterator
{
   public function accept()
   {
      return ($this->key() === 0);
   }
}

$filter_iterator = new myFilterIterator(new ArrayIterator($array_object));

Now, if i do:

print_r(iterator_to_array($filter_iterator));

I get the array I could get if I manually loop through the operator:

Array ( [0] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) )

But what now if I want to work with a RecursiveFilterIterator? Let's say I have:

class myRecursiveFilterIterator extends RecursiveFilterIterator
{
   public function accept()
   {
      return ($this->hasChildren() || $this->key() === 0);
   }
}

$recursive_filter_iterator = new myRecursiveFilterIterator(new RecursiveArrayIterator($array_object));

As you see, this will accept only key 0 for each array contained in the parent array. And so it works if I recursive iterate over it:

foreach (new RecursiveIteratorIterator($recursive_filter_iterator) as $value) {
   print_r($value);
   echo '<br />';
}

Results in:

1
5
9

But, how could I get quickly the array array(array(1), array(5), array(9)) ?

If I do:

print_r(iterator_to_array($recursive_filter_iterator));

or

print_r(iterator_to_array($recursive_filter_iterator->getInnerIterator()));

or

$it = new RecursiveIteratorIterator($recursive_filter_iterator);
print_r(iterator_to_array($it->getInnerIterator()));

I get whole original array:

Array ( [0] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) [1] => Array ( [0] => 5 [1] => 6 [2] => 7 [3] => 8 ) [2] => Array ( [0] => 9 [1] => 10 [2] => 11 [3] => 12 ) )

If I do:

print_r(iterator_to_array(new RecursiveIteratorIterator($recursive_filter_iterator)));

I get just first item:

Array ( [0] => 9 )

If I do:

print_r(iterator_to_array(new RecursiveIteratorIterator($recursive_filter_iterator->getInnerIterator())));

I get last item in my parent array but with key 0:

Array ( [0] => 9 [1] => 10 [2] => 11 [3] => 12 ) 

What I need is to get the array:

Array ( [0] => Array ( [0] => 1 ) [1] => Array ( [0] => 5 ) [2] => Array ( [0] => 9 ) ) 

I know I can get it manually looping, but I want to know if there is a direct way, like in iterator_to_array for not recursive iterators. Sure there is something I don't understand about recursive iterators in PHP, but its documentation is really bad in this.

Thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小…红帽 2025-01-08 16:24:58

目前尚不完全清楚您真正想要做什么,但以下内容需要一个 RecursiveArrayIterator(注意:ArrayObject 不是递归迭代器)并使用 iterator_to_array() 来获取您想要的结果数组。

class FirstOnlyRecursiveArrayIterator extends ParentIterator {
    public function __construct(RecursiveArrayIterator $it) {
         parent::__construct($it);
    }
    public function current() {
        $children = parent::current();
        return array_slice($children, 0, 1);
    }
}

$array_it = new RecursiveArrayIterator(array(
    array('1', '2', '3', '4'),
    array('5', '6', '7', '8'),
    array('9', '10', '11', '12'),
));

$filter_iterator = new RecursiveIteratorIterator(
    new FirstOnlyRecursiveArrayIterator($array_it),
    RecursiveIteratorIterator::SELF_FIRST);
print_r(iterator_to_array($filter_iterator));

It is not entirely clear what you are really wanting to do, but the following takes a RecursiveArrayIterator (note: ArrayObject is not a recursive iterator) and uses iterator_to_array() to get the resulting array that you want.

class FirstOnlyRecursiveArrayIterator extends ParentIterator {
    public function __construct(RecursiveArrayIterator $it) {
         parent::__construct($it);
    }
    public function current() {
        $children = parent::current();
        return array_slice($children, 0, 1);
    }
}

$array_it = new RecursiveArrayIterator(array(
    array('1', '2', '3', '4'),
    array('5', '6', '7', '8'),
    array('9', '10', '11', '12'),
));

$filter_iterator = new RecursiveIteratorIterator(
    new FirstOnlyRecursiveArrayIterator($array_it),
    RecursiveIteratorIterator::SELF_FIRST);
print_r(iterator_to_array($filter_iterator));
蓝眼睛不忧郁 2025-01-08 16:24:58

您需要/想要使用迭代器吗?您可以使用 php 的内置 array_map() 函数,该函数接受一个数组和一个函数,并将指定的函数应用于数组中的每个元素。所以你可以这样做:

<?php
function get_first($foo)
{ 
    return array_slice($foo, 0, 1); //slice the array right after the first element
}

$array_object = new ArrayObject(array(
     array('1', '2', '3', '4'),
     array('5', '6', '7', '8'),
     array('9', '10', '11', '12'),
));

$new_array = array_map("get_first", $array_object->getArrayCopy());
print_r($new_array);
?>

结果将是:

Array
(
    [0] => Array
        (
            [0] => 1
        )

    [1] => Array
        (
            [0] => 5
        )

    [2] => Array
        (
            [0] => 9
        )
)

如果我误解了你的问题,我深表歉意。

Do you need/want to use iterators? You could use php's built-in array_map() function which takes an array and a function and applies the specified function to each element in the array. So you could do:

<?php
function get_first($foo)
{ 
    return array_slice($foo, 0, 1); //slice the array right after the first element
}

$array_object = new ArrayObject(array(
     array('1', '2', '3', '4'),
     array('5', '6', '7', '8'),
     array('9', '10', '11', '12'),
));

$new_array = array_map("get_first", $array_object->getArrayCopy());
print_r($new_array);
?>

The result will be:

Array
(
    [0] => Array
        (
            [0] => 1
        )

    [1] => Array
        (
            [0] => 5
        )

    [2] => Array
        (
            [0] => 9
        )
)

I apologise if I have misunderstood your question.

时光暖心i 2025-01-08 16:24:58

好的。一种简单的方法可能如下。它扩展了 ArrayIterator 类并重写 current() 函数以返回切片数组:

<?php
class FirstOnlyIterator extends ArrayIterator
{
    public function current()
    {
            $next = parent::current();
            return array_slice($next, 0, 1);
    }
}

$array_object = new ArrayObject(array(
     array('1', '2', '3', '4'),
     array('5', '6', '7', '8'),
     array('9', '10', '11', '12'),
));

$iterator = new FirstOnlyIterator($array_object);

print_r(iterator_to_array($iterator));
?>

OK. One easy way could be the following. It extends the ArrayIterator class and overrides the current() function to return the sliced array:

<?php
class FirstOnlyIterator extends ArrayIterator
{
    public function current()
    {
            $next = parent::current();
            return array_slice($next, 0, 1);
    }
}

$array_object = new ArrayObject(array(
     array('1', '2', '3', '4'),
     array('5', '6', '7', '8'),
     array('9', '10', '11', '12'),
));

$iterator = new FirstOnlyIterator($array_object);

print_r(iterator_to_array($iterator));
?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文