如何访问迭代器中的第一个元素?迭 代迭代器聚合器
我正在使用一个PHP框架,它将SQL结果作为可迭代对象返回。问题是我有一个返回一行的SQL查询,我不想创建一个-循环来获取第一个 - 也是唯一一个 - 元素。foreach
那么我该怎么做呢?
这些不起作用:
$obj->item(0)->propName;
$obj->next()->propName;
$obj[0]->propName;
有什么想法吗?
我正在使用一个PHP框架,它将SQL结果作为可迭代对象返回。问题是我有一个返回一行的SQL查询,我不想创建一个-循环来获取第一个 - 也是唯一一个 - 元素。foreach
那么我该怎么做呢?
这些不起作用:
$obj->item(0)->propName;
$obj->next()->propName;
$obj[0]->propName;
有什么想法吗?
假设“可迭代”,你的意思是对象实现了迭代器
接口,你可以用它来检索当前元素,所以可能是你想要的。$obj->current()
$obj->current()->propName
如果迭代器指针已被移动(例如,如果它用于 不重置指针的 ,则可以在调用 之前调用以将指针设置回第一个元素。foreach
$obj->rewind()
$obj->current()
只有两个类接口可以遍历:迭代器和迭代器聚合(任何其他接口都必须实现其中之一)。
迭代器的第一个元素可以得到如下:
$iterator->rewind();
if (!$iterator->valid()) {
throw new Exception('There is no any element!');
}
$firstElement = $iterator->current();
如果您确定:
$iterator
foreach
break
return
)$iterator->next();
您可以省略上一个示例中的 。$iterator->rewind();
如果您确定 中的元素计数不为零,您甚至可以省略 条件 块测试 。$iterator
$iterator->valid()
因此,如果保留了这些先前的条件,那么您只需要:
$firstElement = $iterator->current();
IteratorAggergate实际上只是一个迭代器或另一个迭代器Aggregate的信封。从逻辑上讲,这意味着最后有一个迭代器。
如果您知道迭代器有多深,只需抓住它并使用,如第一个示例所示:
$iterator = $iteratorAggregate->getIterator();
但是,如果您不知道深度,则可以使用也适用于迭代器的解决方案:
$array = iterator_to_array($iteratorAggregate);
// $array is an ordinary array now
if (count($array) === 0) {
throw new Exception('There is no any element!');
}
$firstElement = reset($array);
不幸的是,在biig数组的情况下,这有点过分了,因为尽管我们只需要一个,但必须创建所有元素的副本。此外,如果迭代器是无限生成器,您将耗尽内存。
有一种解决方案有效:
while ($iterator instanceof \IteratorAggregate) {
$iterator = $iterator->getIterator();
}
// $iterator now contains instance of Iterator
我为一个包含 10000 个成员的数组做了一个简单的基准测试,这个解决方案快了 6 倍。
因此,适用于所有情况的通用解决方案是:
while ($iterator instanceof \IteratorAggregate) {
$iterator = $iterator->getIterator();
}
$iterator->rewind();
if (!$iterator->valid()) {
throw new Exception('There is no any element!');
}
$firstElement = $iterator->current();
拉帕普