Перевірка під час ітерації масиву, якщо поточний елемент є останнім елементом


78

Будь ласка, допоможіть мені перекласти цей псевдокод у справжній php-код:

 foreach ($arr as $k => $v)
    if ( THIS IS NOT THE LAST ELEMENT IN THE ARRAY)
        doSomething();

Редагувати: масив може мати цифрові або рядкові ключі


6
Чому б не використовувати forцикл для count($arr) - 1ітерацій?
Марцін

1
Якщо у вас змішані клавіші, як визначити, який ключ є останнім елементом? Якщо ви хочете, щоб це був останній елемент, доданий до масиву, тоді повинні бути деякі дані, що вказують позначку часу.
Расіка

визначення для last: за внутрішнім порядком масиву. Що ідентично
сказанню

Відповіді:


140

ви можете використовувати кінець PHP ()

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastElement = end($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($v == $lastElement) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}

Оновлення1

як зазначив @Mijoja, вищезазначене може мати проблеми, якщо у вас є одне і те ж значення кілька разів у масиві. нижче - виправлення.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
//point to end of the array
end($array);
//fetch key of the last element of the array.
$lastElementKey = key($array);
//iterate the array
foreach($array as $k => $v) {
    if($k == $lastElementKey) {
        //during array iteration this condition states the last element.
    }
}

Оновлення2

Я знайшов рішення @onteria_ краще, ніж те, на що я відповів, оскільки воно не змінює внутрішній покажчик масивів, я оновлюю відповідь, щоб відповідати його відповіді.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
// Get array keys
$arrayKeys = array_keys($array);
// Fetch last array key
$lastArrayKey = array_pop($arrayKeys);
//iterate array
foreach($array as $k => $v) {
    if($k == $lastArrayKey) {
        //during array iteration this condition states the last element.
    }
}

Дякую @onteria_

Оновлення3

Як вказує @CGundlach, представлений PHP 7.3, array_key_lastякий здається набагато кращим варіантом, якщо ви використовуєте PHP> = 7.3

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastKey = array_key_last($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($k == $lastKey) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}

11
Це матиме проблеми, якщо у вас буде одне і те ж значення кілька разів у масиві
Mijoja

1
@IbrahimAzharArmar Щойно знайшов цю відповідь, і, впроваджуючи ваше рішення, я помітив, що з PHP 7.3 тепер існує функція array_key_last, яка також повертає останній ключ масиву, не впливаючи на внутрішній вказівник: secure.php.net/array_key_last . Ще більше спростило б своє рішення :)
CGundlach 02

1
@CGundlach це добре знати. Оновить відповідь. Дякую.
Ібрагім Азхар

26

Це завжди робить трюк для мене

foreach($array as $key => $value) {
   if (end(array_keys($array)) == $key)
       // Last key reached
}

Редагувати 30.04.15

$last_key = end(array_keys($array));
reset($array);

foreach($array as $key => $value) {
  if ( $key == $last_key)
      // Last key reached
}

Щоб уникнути попередження E_STRICT, згаданого @Warren Sergent

$array_keys = array_keys($array);
$last_key = end($array_keys);

набагато елегантніше і легше! :)
Рафаель Моні

Я не впевнений, чому цей коментар не є прийнятою відповіддю. Це далеко не найпростіша / найчистіша з усіх наданих відповідей і працює для переважної більшості можливих випадків використання (тобто асоціативних та перерахованих масивів).
Пірс

1
@Pierce, щоб дати вам підказку: на це відповіли через 3 з половиною роки після прийнятої відповіді, а якщо у вас 1000 елементів у вашому масиві, ви 1000 разів подзвоните "end" та "array_keys".
StefanNch

Очевидно, це має проблеми з продуктивністю, якщо ви ітераціюєте над великим масивом. У цьому випадку я пропоную перемістити кінець (array_keys ($ array)) поза цикл. Але обов’язково скиньте масив перед ітерацією.
Річард Мерчант,

Якщо ви хочете бути педантичним, у суворому режимі end (array_keys ($ array)) викликатиме повідомлення, оскільки «Лише змінні повинні передаватися за посиланням» - щоб це виправити, визначте $ array_keys = array_keys ($ array) і викличте end () для змінної $ array_keys.
Уоррен Серджент

14
$myarray = array(
  'test1' => 'foo',
  'test2' => 'bar',
  'test3' => 'baz',
  'test4' => 'waldo'
);

$myarray2 = array(
'foo',
'bar',
'baz',
'waldo'
);

// Get the last array_key
$last = array_pop(array_keys($myarray));
foreach($myarray as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

// Get the last array_key
$last = array_pop(array_keys($myarray2));
foreach($myarray2 as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

Оскільки array_popробота над тимчасовим масивом, створеним array_keysним, зовсім не змінює вихідний масив.

$ php test.php
test1 -> foo
test2 -> bar
test3 -> baz
0 -> foo
1 -> bar
2 -> baz

Мені це подобається краще за прийняту відповідь, оскільки для ініціалізації за межами циклу потрібен лише один рядок.
Джордан Лев

Мені це подобається більше, ніж прийнята відповідь, тому що це не змінює внутрішній вказівник масиву, який ви збираєтеся виконати.
автонімічний

зробити те саме для першого елемента$first = array_shift(array_keys($myarray2));
Луки

2
Це видає повідомлення в E_STRICT: Примітка про час виконання: За допомогою посилання слід передавати лише змінні
Vigintas Labakojis,

Здається, це кращий підхід, ніж моя відповідь, оновлення моєї відповіді.
Ібрагім Азхар Армар

6

Чому б не цей дуже простий метод:

$i = 0; //a counter to track which element we are at
foreach($array as $index => $value) {
    $i++;
    if( $i == sizeof($array) ){
        //we are at the last element of the array
    }
}

2

Я знаю, що це старе, і використання ітератора SPL може бути просто надмірним, але в будь-якому випадку тут є інше рішення:

$ary = array(1, 2, 3, 4, 'last');
$ary = new ArrayIterator($ary);
$ary = new CachingIterator($ary);
foreach ($ary as $each) {
    if (!$ary->hasNext()) { // we chain ArrayIterator and CachingIterator
                            // just to use this `hasNext()` method to see
                            // if this is the last element
       echo $each;
    }
}

1

Моє рішення, також досить просте ..

$array = [...];
$last = count($array) - 1;

foreach($array as $index => $value) 
{
     if($index == $last)
        // this is last array
     else
        // this is not last array
}

Це досить приємно і просто, якщо ваші ключі масиву були автоматично згенеровані.
Метт Кіран

0

Якщо елементи впорядковані чисельно, використовуйте функцію key (), щоб визначити індекс поточного елемента та порівняти його з довжиною. Вам потрібно було б використовувати next () або prev (), щоб прокручувати елементи в циклі while замість циклу for:

$length = sizeOf($arr);
while (key(current($arr)) != $length-1) {
    $v = current($arr); doSomething($v); //do something if not the last item
    next($myArray); //set pointer to next item
}

Бо це перше, що я знайшов, коли погуглив. Добре знати всі різні способи робити одне і те ж і краще розбиратися. : D
trusktr

1
Не буде працювати для
нечисельних чи несуворо

0
$arr = array(1, 'a', 3, 4 => 1, 'b' => 1);
foreach ($arr as $key => $val) {
    echo "{$key} = {$val}" . (end(array_keys($arr))===$key ? '' : ', ');
}
// output: 0 = 1, 1 = a, 2 = 3, 4 = 1, b = 1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.