可以修改foreach架构吗?

时间:2011-02-09 11:00:10

标签: php foreach

这是一个奇怪的问题,但它很有趣所以我想我会问。假设我不喜欢php的foreach循环如何操作,我总是以格式使用它,我所做的就是在外面添加一个计数器并在foreach循环中使用它来判断我们是否'在最后一个元素中。

$counter = 1;
$array_size = count($array);
foreach($array as $item){
   //code
   if($counter == $array_size){ 
      $isLast = true 
   } else {
      $isLast = false; 
   }
   $counter++; 
}

我的问题是:我可以覆盖或分叉或继承(或任何你想称之为)原始的php foreach循环以包含这个新功能,这样我现在可以做到这一点,而无需初始化计数器和这样。

newforeach($array as $item){
   //code
   $isLast = //something that returns true/false;
}

这是一个有趣的想法,所以我想知道这里的一个铁杆php家伙能否以某种方式使这成为可能?或者这种修改方式过于复杂而不会破坏语言本身?!

5 个答案:

答案 0 :(得分:4)

你可以编写一个包含你正在迭代的数组的类(你需要让它实现Iterator interface),并使用isLast()方法为你执行此检查。

像这样(伪代码):

$arrayIterator = new MyArrayIterator($myArray);

foreach ($arrayIterator as $item)
{
  if ($arrayIterator->isLast())
  {
    doStuff();
  }
}

答案 1 :(得分:2)

这似乎是一种奇怪的做事方式。为什么不这样做:

$isLast = FALSE;
foreach( $array as $count => $item )
{
    $isLast = ($count+1 == count($array))
}

我确定其他人可以清理该代码,自从我编写PHP以来已经有一段时间了。

或者,如果你喜欢这样做的话,为什么不把你的if / then / else放到一个函数说isLast,然后像这样调用它:

$isLast = isLast($item, $array)

答案 2 :(得分:2)

如果你的问题只是“你可以覆盖php的语言结构的实现”,答案是否定的。这是其他动态语言的一个功能,如Javascript或Ruby,通常称为Monkey Patching或Duck Punching。

答案 3 :(得分:1)

您可以将foreach重写为while循环,并使用next()遍历项目,如下所示:

$array = array('a' => 'hi', 2 => 2515, 'as' => 'foo');
while (true) {
    $item = current($array);
    echo $item, "\n";
    if (!next($array)) {
        echo '^last item!';
        break;
    }
}

答案 4 :(得分:0)

你可以这样做(不修改语法):

function foreach_counter($ar, $callback) {
  $counter = 1;
  $array_size = count($ar);
  foreach($ar as $item){
    $callback($item, $counter, $counter == $array_size);
    $counter++; 
  }
}

foreach_counter(array('a','b'), function($item, $counter, $isLast) {
     echo $counter . ': ' . $item . '' . ($isLast ? 'END' : ',');
});
// outputs 1: a, 2: b END

然而,正如你所看到的,阅读简洁版本变得更加困难,所以尽管你可以,但你不应该这样做 - 特别是只要你刚刚开始理解php。

通常,您希望在这样的循环中构建字符串。请使用implode

echo implode(', ', array(1,2,3));
// output: 1, 2, 3