PHP - при использовании foreach для обхода массива, как я могу определить, нахожусь ли я на последней паре? - PullRequest
6 голосов
/ 18 августа 2010

Я пытаюсь «красиво распечатать» массив, используя синтаксис вроде:

$outString = "[";
foreach($arr as $key=>$value) {
    // Do stuff with the key + value, putting the result in $outString.
    $outString .= ", ";
}
$outString .= "]";

Однако очевидным недостатком этого метода является то, что в конце он будет показывать «,»распечатки массива перед закрытием "]".Есть ли хороший способ использования синтаксиса $ key => $ value для определения, находитесь ли вы в последней паре в массиве, или я должен переключиться на цикл, используя вместо этого each()?

Ответы [ 8 ]

12 голосов
/ 18 августа 2010

Создайте массив, а затем используйте implode:

$parts = array();
foreach($arr as $key=>$value) {
    $parts[] = process($key, $value);
}

$outString = "[". implode(", ", $parts) . "]";
4 голосов
/ 18 августа 2010

Выполните обработку отдельно, а затем используйте implode(), чтобы присоединиться:

$outArr = array();
foreach($arr as $key => $value) {
    $outArr[] = process($key, $value);
}
$outString = '[' . implode(', ', $outArr) . ']';
4 голосов
/ 18 августа 2010

Вы можете просто обрезать последние ",", когда for завершается, используя подстроку.

$outString = "[";
foreach($arr as $key=>$value) {
  // Do stuff with the key + value, putting the result in $outString.
  $outString .= ", ";
 }

 $outString = substr($outString,-2)."]";  //trim off last ", "
3 голосов
/ 18 августа 2010

Несмотря на обстоятельства вашего примера (объединение строк с запятыми, для которых implode - правильный путь для этого), чтобы ответить на ваш конкретный вопрос, канонический способ перебрать массив и проверить если вы на последнем элементе используете CachingIterator :

<?php
$array = array('k'=>'v', 'k1'=>'v1');

$iter = new CachingIterator(new ArrayIterator($array));
$out = '';
foreach ($iter as $key=>$value) {
    $out .= $value;

    // CachingIterator->hasNext() tells you if there is another
    // value after the current one.
    if ($iter->hasNext()) {
        $out .= ', ';
    }
}
echo $out;
2 голосов
/ 18 августа 2010

Может быть проще сделать это следующим образом и добавить запятую к строке перед элементом, если это не первый элемент.

$first= true;
foreach ($arr as $key => $value) {
    if (! $first) {
        $outString .=', ';
    } else {
      $first = false;
    }

    //add stuff to $outString
}

Выходной формат - JSON?Если это так, вы можете использовать json_encode().

1 голос
/ 18 августа 2010

Я стараюсь избегать использования петель в таких ситуациях.Вы должны использовать implode () для объединения списков с общим разделителем и использовать array_map () для обработки любой обработки в этом массиве перед объединением.Обратите внимание на следующие реализации, которые должны выражать универсальность этих функций.Карта массивов может принимать строку (имя функции), представляющую либо встроенную функцию, либо определяемую пользователем функцию (первые 3 примера).Вы можете передать ему функцию с помощью create_function () или передать лямбда / анонимную функцию в качестве первого параметра.

$a = array(1, 2, 3, 4, 5);

// Using the user defined function
function fn ($n) { return $n * $n; }
printf('[%s]', implode(', ', array_map('fn', $a)));
// Outputs: [1, 4, 9, 16, 25]

// Using built in htmlentities (passing additional parameter
printf('[%s]', implode(', ', array_map( 'intval' , $a)));
// Outputs: [1, 2, 3, 4, 5]

// Using built in htmlentities (passing additional parameter
$b = array('"php"', '"&<>');
printf('[%s]', implode(', ', array_map( 'htmlentities' , $b, array_fill(0 , count($b) , ENT_QUOTES) )));
// Outputs: [&quot;php&quot;, &quot;&amp;&lt;&gt;]

// Using create_function <PHP 5
printf('[%s]', implode(', ', array_map(create_function('$n', 'return $n + $n;'), $a)));
// Outputs: [2, 4, 6, 8, 10]

// Using a lambda function (PHP 5.3.0+)
printf('[%s]', implode(', ', array_map(function($n) { return $n; }, $a)));
// Outputs: [1, 2, 3, 4, 5]
1 голос
/ 18 августа 2010

Есть много возможностей.Я думаю, это одно из самых простых решений:

$arr = array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd', 4 => 'e', 5 => 'f', 6 => 'g');

echo '[', current($arr);
while ($n = next($arr)) echo ',', $n;
echo ']';

Выходы:

[a,b,c,d,e,f,g]
1 голос
/ 18 августа 2010

Вы можете сделать это как обычный цикл for:

$outString = "[";
for ($i = 0; $i < count($arr); $i++) {
   // Do stuff
   if ($i != count($arr) - 1) {
      $outString += ", ";
   }
 }

Однако самый хороший способ сделать это, ИМХО, сохранить все компоненты в массиве, а затем сжать:

 $outString = '[' . implode(', ', $arr) . ']';

implode () берет все элементы в массиве и объединяет их в строку, разделив ее первым аргументом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...