Как найти индекс foreach?


490

Можно ли найти foreachиндекс?

в forцикле следующим образом:

for ($i = 0; $i < 10; ++$i) {
   echo $i . ' ';
}

$i даст вам индекс.

Нужно ли использовать forцикл или есть какой-то способ получить индекс в foreachцикле?

Ответы:


909
foreach($array as $key=>$value) {
    // do stuff
}

$keyиндекс каждого $arrayэлемента


2
Зависит от того, что ОП означает под индексом: <? $ a = массив (3,5, 'xx', 4312, 'sasas'); снята с охраны ($ в [3]); foreach ($ a as $ k => $ v) print "\ $ k = $ k и \ $ v = $ v"; ?>
Милен А. Радев

9
определенно, этот вопрос не очень специфичен, я понял, что ОП в значительной степени не знал о синтаксисе $ key => $ value
Оуэн,

38
ну, это на самом деле правильно, но не должно быть принятым ответом, так как ключ тоже может быть строкой. говорят, что у вас $myarr['foo'] = 'bar';этот метод не удался
Toskan

12
@ Зубр ты прав в том смысле, что он не подведет. Но он не отвечает требованиям ОП. Он ищет числовые значения, такие как n-й элемент.
Тоскан

3
Как говорит @Toskan, это не должно быть принятым ответом. Я думаю, что лучше просто создать переменную вне цикла и отсчитывать оттуда, увеличивая ее vatiable++;на каждой итерации. Традиционный способ, но всегда работал.
Jomar Sevillejo

172

Вы можете поместить в свой хак foreach, например, поле, увеличиваемое при каждом проходе, что в точности и forдает цикл в числовом индексированном массиве. Такое поле будет псевдоиндексом, который требует ручного управления (приращения и т. Д.).

A foreachдаст вам ваш индекс в форме вашего $keyзначения, поэтому такой взлом не должен быть необходимым.

например, в foreach

$index = 0;
foreach($data as $key=>$val) {
    // Use $key as an index, or...

    // ... manage the index this way..
    echo "Index is $index\n";
    $index++;
}

128
Увеличение значения в цикле вряд ли является «взломом».
Томас МакКейб

17
@ThomasMcCabe Можно даже сказать, что это одно из основных применений для цикла.
Бизон

26

Следует отметить, что вы можете вызвать key()любой массив, чтобы найти текущий ключ, для которого он включен. Как вы можете догадаться current(), вернет текущее значение и next()переместит указатель массива на следующий элемент.


Это может быть полезно, если вы хотите использовать обычный старый ассоциативный массив PHP для хранения данных, которые должны быть представлены через интерфейс Iterable (где вам нужно отслеживать, где вы находитесь в цикле).
Питер

2
+1 для альтернативы, но вызов функции в каждой итерации немного тяжелее, чем использование предварительно назначенных переменных (т. Е. Использование $keyfrom $key=>$value) ... Однако я держу пари, что низкая производительность незначительна / ощутима в простом цикле.
Armfoot

20

Оуэн имеет хороший ответ. Если вам нужен только ключ, и вы работаете с массивом, это также может быть полезно.

foreach(array_keys($array) as $key) {
//  do stuff
}

4
И если вам нужен индекс foreach(array_keys($array) as $index=>$key).
Лев

14

Вы можете создать $iвне цикла и сделать $i++в нижней части цикла.


16
Важно отметить, что этот подход дает текущую итерацию цикла, а НЕ текущий индекс итеративного массива.
Питер Бейли

8

Эти две петли эквивалентны (конечно, за исключением перил безопасности):

for ($i=0; $i<count($things); $i++) { ... }

foreach ($things as $i=>$thing) { ... }

например

for ($i=0; $i<count($things); $i++) {
    echo "Thing ".$i." is ".$things[$i];
}

foreach ($things as $i=>$thing) {
    echo "Thing ".$i." is ".$thing;
}

17
Нет, если это ассоциативный массив
JoeCortopassi


5

Джонатан прав. PHP-массивы действуют как таблица сопоставления ключей для значений. в некоторых случаях вы можете получить индекс, если ваш массив определен, например:

$var = array(2,5);

for ($i = 0; $i < count($var); $i++) {
    echo $var[$i]."\n";
}

ваш вывод будет

2
5

в этом случае каждый элемент в массиве имеет понятный индекс, но если вы затем делаете что-то вроде следующего

$var = array_push($var,10);

for ($i = 0; $i < count($var); $i++) {
    echo $var[$i]."\n";
}

вы не получите выход. Это происходит потому, что массивы в PHP не являются линейными структурами, как в большинстве языков. Они больше похожи на хеш-таблицы, которые могут иметь или не иметь ключи для всех сохраненных значений. Следовательно, foreach не использует индексы для обхода, потому что они имеют индекс, только если массив определен. Если вам нужен индекс, убедитесь, что ваши массивы полностью определены, прежде чем переходить по ним, и используйте цикл for.


Да, именно поэтому в PHP мы должны «объединять массивы» по ключам, а не по индексам ... См. Также array_map (func, $ a, $ b).
Питер Краусс

Опс, дорогой читатель и @TheBrawnyMan, помните также, что ваш пример похож на ошибку array_push () (!). Рекомендуется использовать $var[] = 10;(см. Руководство по PHP-ссылке), поэтому второй forцикл выводит ожидаемые результаты.
Питер Краусс

4

Массивы PHP имеют внутренние указатели, поэтому попробуйте это:

foreach($array as $key => $value){
   $index = current($array);
}

Работает хорошо для меня (только очень предварительно проверено, хотя).


1

Обычно я делаю это при работе с ассоциативными массивами:

foreach ($assoc_array as $key => $value) {
 //do something
}

Это будет хорошо работать и с неассоциативными массивами. Ключ $ будет значением индекса. Если вы предпочитаете, вы можете сделать это тоже:

foreach ($array as $indx => $value) {
  //do something
}

4
Для чего нужна «альтернатива»? Вы знаете, что это то же самое, кроме имен переменных? Так что последнее предложение и блок кода не нужны, я бы сказал - если это что-то делает, это просто сбивает с толку ..
Dennis98

@ Dennis98 Разница в том, что один из них имеет ассоциативный массив в качестве входа, а другой - числовой массив. Хотя, думаю, было бы лучше, если бы ответ был немного более подробным.
I_ATE_YOUR_WORK_FILES

0

Я хотел бы добавить это, я использовал это в laravel, чтобы просто проиндексировать мою таблицу:

  • С $ loop-> index
  • Я также преинкрементую это с циклом ++ $, чтобы начать с 1

Мой код:

@foreach($resultsPerCountry->first()->studies as $result)
  <tr>
    <td>{{ ++$loop->index}}</td>                                    
  </tr>
@endforeach

Этот вопрос не был задан для Laravel. $loopПеременная не может быть использована , так как просили общего PHP.
Озгюр Кан

0

Я решил это так, когда мне пришлось использовать индекс и значение foreach в одном контексте:

$array = array('a', 'b', 'c');
foreach ($array as $letter=>$index) {

  echo $letter; //Here $letter content is the actual index
  echo $array[$letter]; // echoes the array value

}//foreach

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.