2013-01-22 56 views
14

我正在使用PHP框架将SQL结果作为迭代对象返回。问题是我有一个返回一行的SQL查询,我不想创建一个foreach -loop来获取第一个也是唯一的元素。如何访问迭代器中的第一个元素?

那我该怎么做呢?

这些不工作:

$obj->item(0)->propName; 
$obj->next()->propName; 
$obj[0]->propName; 

任何想法?

+3

'$ obj->电流() - > propName'吧? – Crisp

+2

放了一个'var_dump'并检查结果对象的结构 –

+0

Crisp的答案没有办法。做出一个单独的答案,我会将其标记为答案。 var_dump给了我这样无用的垃圾:http://pastebin.com/GeNDbiN4 – neubert

回答

13

假设通过“迭代”,您的意思是该对象实现Iterator interface,您可以使用$obj->current()检索当前元素,因此$obj->current()->propName可能是你想要的。

如果迭代指针已被移动(例如,如果它是在一个foreach,不复位指针使用),那么你可以调用$obj->rewind()你打电话$obj->current()之前设置指针回到第一个元素。

6

只有可以穿越类接口:IteratorIteratorAggregate任何其他必须执行这些之一)。


迭代

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(); 

IteratorAggregate

你不能获得第一要素的任何简单。 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

相关问题