Вопрос прост. У меня есть foreach
цикл в моем коде:
foreach($array as $element) {
//code
}
В этом цикле я хочу по-разному реагировать, когда мы находимся в первой или последней итерации.
Как это сделать?
Вы можете использовать счетчик:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
array_shift
иarray_pop
. Хотя это решение, которое я придумал, если бы мне пришлось реализовать такую вещь, я бы теперь придерживался ответа Рок Краля .$i = 1
, вам не нужно беспокоиться$len - 1
, просто используйте$len
.Если вы предпочитаете решение, которое не требует инициализации счетчика вне цикла, я предлагаю сравнить текущий ключ итерации с функцией, которая сообщает вам последний / первый ключ массива.
Это становится несколько более эффективным (и более читабельным) с выходом PHP 7.3.
Решение для PHP 7.3 и выше:
Решение для всех версий PHP:
источник
end()
+key()
на каждой итерации цикла - если это оба, то каждый раз вызывается 4 метода. Конечно, это были бы очень легкие операции и, вероятно, просто поиск по указателю, но затем документы продолжают указывать этоreset()
иend()
изменяют внутренний указатель массива - так это быстрее, чем счетчик? возможно нет.reset()
вызов перед foreach и кэшировать результат в$first
.Чтобы найти последний элемент, я считаю, что этот фрагмент кода работает каждый раз:
источник
next
: Warning Эта функция может возвращать логическое значениеFALSE
, но также может возвращать и не логическое значение, которое оценивается какFALSE
. Пожалуйста, прочитайте раздел о логических значениях для получения дополнительной информации. Используйте===
оператор для проверки возвращаемого значения этой функции.[true,true,false,true]
. Но лично я буду использовать это всякий раз, когда имею дело с массивом, который не содержит логическое значениеfalse
.next()
не должны НИКОГДА быть использованы внутри цикла Еогеасп. Это портит внутренний указатель массива. Проверьте документацию для получения дополнительной информации.Более упрощенная версия вышеупомянутого и предполагающая, что вы не используете пользовательские индексы ...
Версия 2 - потому что я пришел, чтобы ненавидеть, используя остальное, если не нужно.
источник
if ($index == count($array) - 1)
. Смотрите здесь .Вы можете удалить первый и последний элементы из массива и обрабатывать их отдельно.
Нравится:
Удаление всего форматирования в CSS вместо встроенных тегов улучшит ваш код и ускорит время загрузки.
Вы также можете по возможности избегать смешивания HTML с логикой php.
Ваша страница может быть сделана намного более читаемой и поддерживаемой, если разделить такие вещи:
источник
Попытка найти первое будет:
источник
Просто это работает!
Спасибо, @billynoah, за то, что вы решили проблему в конце .
источник
if ($key === $lastkey)
.if ($lastkey === $key)
?PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
получает целое число, а неend()
.end()
« возвращает значение последнего элемента » иkey()
ожидает массив в качестве входных данных.1: Почему бы не использовать простое
for
утверждение? Предполагая, что вы используете реальный массив, а не a,Iterator
вы можете легко проверить, равна ли переменная counter 0 или единица меньше целого числа элементов. На мой взгляд, это самое чистое и понятное решение ...2: Вы должны рассмотреть возможность использования Nested Sets для хранения вашей древовидной структуры. Кроме того, вы можете улучшить все это с помощью рекурсивных функций.
источник
for
вы можете1
перейти отn-1
и кif
S и из тела. Нет смысла проверять их повторно.Лучший ответ:
источник
Наиболее эффективный ответ от @morg, в отличие от этого
foreach
, работает только для правильных массивов, а не для объектов хэш-карты. Этот ответ позволяет избежать накладных расходов на условный оператор для каждой итерации цикла, как и в большинстве этих ответов (включая принятый ответ), специально обрабатывая первый и последний элемент и циклически обрабатывая средние элементы.array_keys
Функция может быть использована для эффективной работы ответа , какforeach
:Я еще не сделал сравнительный анализ, но в цикле не было добавлено никакой логики, которая была бы самым большим ударом по производительности, поэтому я подозреваю, что тесты, обеспеченные эффективным ответом, довольно близки.
Если вы хотели функционализировать подобные вещи, я попробовал здесь такую функцию iterateList . Хотя, возможно, вы захотите сравнить основной код, если вы очень заинтересованы в эффективности. Я не уверен, сколько накладных расходов вносит все вызовы функций.
источник
Для сценариев, генерирующих SQL-запросы, или для всего, что выполняет другое действие для первого или последнего элемента, гораздо быстрее (почти в два раза быстрее) избежать ненужных проверок переменных.
Текущее принятое решение использует цикл и проверку внутри цикла, которая будет выполняться every_single_iteration, правильный (быстрый) способ сделать это заключается в следующем:
Небольшой домашний тест показал следующее:
test1: 100000 прогонов модели Морг
время: 1869.3430423737 миллисекунд
test2: 100000 прогонов модели, если последний
время: 3235.6359958649 миллисекунд
И поэтому совершенно ясно, что проверка стоит дорого, и, конечно, она становится еще хуже, чем больше переменных вы добавляете;)
источник
$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;
будет выводить:0: , 1: One, 2: ,
array()
создан,{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
но пустые элементы игнорируются с помощью count, вы подсчитываете количество определенных «вещей» !! BOUNTY ЖЕРТВЫ ВХОДЯТ! Этот ответ заслуживает награды, но если @Morg. ушел, это бессмысленно. Я бы дал щедрость человеку, который, вероятно, больше не будет использовать SO! Если он вернется и улучшит свой ответ, он заслуживает награды!array_keys
функции, которую вы можете рассматривать как массив. Смотрите мой "улучшенный" ответ .$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
С ключами и значениями это работает также:
источник
Использование логической переменной по-прежнему наиболее надежно, даже если вы хотите проверить первое появление
$value
(я нашел это более полезным в моей ситуации и во многих ситуациях) , например, так:Тогда как
!next( $array )
найти последний,$value
который вернется,true
если нетnext()
значения для итерации.И я предпочитаю использовать
for
цикл вместо того,foreach
чтобы использовать счетчик, например так:источник
Я наткнулся на эту тему, когда у меня такая же проблема. Мне нужно только получить первый элемент, а затем повторно анализировать свой код, пока это не пришло мне в голову.
Вышеуказанные коды хороши и полны, но если вам нужен только первый элемент, вы можете попробовать этот код.
источник
Не уверен, если это все еще необходимо. Но следующее решение должно работать с итераторами и не требует
count
.источник
Вы также можете использовать анонимную функцию:
Следует упомянуть еще три вещи:
array_values
сначала передать его в массив .$element
вы должны передать его по ссылке (&$element
).$indexOfLastElement
внутриuse
конструкции, опять - таки по ссылке , если это необходимо.источник
Вы можете использовать счетчик и длину массива.
источник
источник
Использование reset ($ array) и end ($ array)
Демо repl.it
источник
Попробуй это:
источник