在Php中迭代迭代器时,例如symfonys-finder(composer require symfony/finder
):
$files = 'Symfony'Component'Finder'Finder::create()
->in('searchdir')
->directories()
->depth(0)
->sortByType();
foreach ($files as $file) {
//is $file the last element?
}
检查$file
是否是$files
迭代器中的最后一项的最佳方法是什么?
如果你在迭代某个东西,并且你真的很关心项目的索引,你可以使用经典的结构:
for($i=0; $i<count($iterator);$i++) {
if($i==count($iterator)-1) {
// You reached the last item
}
}
或者也可以像这样使用$key=>$value:
foreach($iterator as $iteratorKey=>$iteratorValue) {
if($iteratorKey==count($iterator)-1) {
// You reached the last item
}
}
由于我收到的两个问题答案都是明显错误的,让我用我发现的答案来回答:
方法1
你可以得到最后一个这样的密钥:
$last = null;
foreach($files as $key => $value) {
$last = $key;
}
然后比较迭代中的密钥:
foreach ($iterator as $key => $value) {
if ($key === $last) {
....
}
}
方法2
如果迭代器实现了seek
方法并且是Countable
(或者有一个count
-方法),那么您也可以获得最后一个密钥,如下所示:
$iterator->seek(count($iterator) - 1);
$last = $iterator->key();
起初,这似乎是一个更干净的解决方案,但根据我对symfonys finder类的测试(5000个文件,对两种方法都测试了100次),这大约是使用foreach函数的3倍慢。专家能解释一下原因吗?
方法3
我现在使用的解决方案是这样的,因为它尽可能减少开销(如果迭代器不是Countable
(大多数都是),请使用迭代器计数而不是count
):
$index = 0;
$length = count($iterator);
foreach ($iterator as $item) {
$index++;
if ($index == $length) {
// last item!
}
}
您也可以这样做:
$cachingIterator = new 'CachingIterator($iterator, 'CachingIterator::FULL_CACHE);
while ($iterator->valid()) {
$cachingIterator->next();
}
$lastKey = $cachingIterator->key();
$lastCurrentValue = $cachingIterator->current();
这在loopwp/collection的Last操作中实现。