Можно ли модифицировать архитектуру foreach? - PullRequest
1 голос
/ 09 февраля 2011

Это странный вопрос, но он интересный, поэтому я решил спросить.Допустим, мне не нравится, как работает цикл foreach в php, и я всегда использую его в формате, где все, что я сделал, это добавил счетчик снаружи и использовал его внутри цикла 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 ]

4 голосов
/ 09 февраля 2011

Вы можете написать класс, который обертывает массив, по которому вы перебираете (вам нужно, чтобы он реализовал интерфейс Iterator ) с помощью метода isLast (), который выполняет эту проверку за вас.

Примерно так (псевдокод):

$arrayIterator = new MyArrayIterator($myArray);

foreach ($arrayIterator as $item)
{
  if ($arrayIterator->isLast())
  {
    doStuff();
  }
}
2 голосов
/ 09 февраля 2011

Если ваш вопрос просто «можете ли вы переопределить реализацию языковых конструкций php», ответ - нет. Это особенность других динамических языков, таких как Javascript или Ruby, часто называемых Monkey Patching или Duck Punching.

2 голосов
/ 09 февраля 2011

Кажется странным способом делать вещи. Почему бы просто не иметь что-то вроде этого:

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

Я уверен, что кто-то еще может очистить этот код, прошло много времени с тех пор, как я написал PHP.

В качестве альтернативы, если вам нравится ваш способ сделать это, почему бы просто не поместить ваш if / then / else в функцию, скажем isLast, и вызвать ее так:

$isLast = isLast($item, $array)

1 голос
/ 09 февраля 2011

Вы можете переписать ваш 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;
    }
}
0 голосов
/ 09 февраля 2011

Вы можете сделать это (без изменения синтаксиса):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...