我正在使用PHP框架将SQL结果作为迭代对象返回。问题是我有一个返回一行的SQL查询,我不想创建一个foreach
-loop来获取第一个也是唯一的元素。如何访问迭代器中的第一个元素?
那我该怎么做呢?
这些不工作:
$obj->item(0)->propName;
$obj->next()->propName;
$obj[0]->propName;
任何想法?
我正在使用PHP框架将SQL结果作为迭代对象返回。问题是我有一个返回一行的SQL查询,我不想创建一个foreach
-loop来获取第一个也是唯一的元素。如何访问迭代器中的第一个元素?
那我该怎么做呢?
这些不工作:
$obj->item(0)->propName;
$obj->next()->propName;
$obj[0]->propName;
任何想法?
假设通过“迭代”,您的意思是该对象实现Iterator
interface,您可以使用$obj->current()
检索当前元素,因此$obj->current()->propName
可能是你想要的。
如果迭代指针已被移动(例如,如果它是在一个foreach
,不复位指针使用),那么你可以调用$obj->rewind()
你打电话$obj->current()
之前设置指针回到第一个元素。
只有可以穿越类接口:Iterator和IteratorAggregate(任何其他必须执行这些之一)。
Iterator的第一个元素可以按如下方式获得:
$iterator->rewind();
if (!$iterator->valid()) {
throw new Exception('There is no any element!');
}
$firstElement = $iterator->current();
如果你是肯定的:
$iterator
从未被foreach
走过,或如果是这样,但循环从未停止过break;
$iterator->next();
你可以从前面的例子中省略$iterator->rewind();
。
如果您确定$iterator
中元素的个数为而非为零,您甚至可以省略条件块测试$iterator->valid()
。
所以,如果这些以前的情况将被保留,那么你所需要的仅仅是:
$firstElement = $iterator->current();
你不能获得第一要素的任何简单。 IteratorAggergate实际上只是一个Iterator或另一个IteratorAggregate的信封。从逻辑上讲,这意味着最后有一个迭代器。不幸的是,你不知道有多少层次。
实现的第一个元素的最简单的方法是:
$array = iterator_to_array($iteratorAggregate);
if (count($array) === 0) {
throw new Exception('There is no any element!');
}
$firstElement = reset($array);
(!令人惊讶的完全相同的解决方案也适用于一个迭代)
我们将其转化为一个普通的数组所以下一个程序是usual way to fetch the first element from an array。 不幸的是在biig阵列的情况下,这是一个小矫枉过正因为所有元素的副本必须创建,尽管我们只需要一个。
有一个解决方案,似乎松懈:
while ($iteratorAggregate instanceof \IteratorAggregate) {
$iteratorAggregate = $iteratorAggregate->getIterator();
}
$iterator = $iteratorAggregate;
并在下一步中,我们与它的工作就像是在第一个示例的迭代器。我为一个10000个成员阵列做了一个简单的基准测试,这个解决方案几乎快了6倍。
LLAP
'$ obj->电流() - > propName'吧? – Crisp
放了一个'var_dump'并检查结果对象的结构 –
Crisp的答案没有办法。做出一个单独的答案,我会将其标记为答案。 var_dump给了我这样无用的垃圾:http://pastebin.com/GeNDbiN4 – neubert