2015-06-30 2 views
12

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

$mainArray = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 
$size  = count($mainArray); 
$circular = array('A', 'B', 'C'); 

for($i = 0; $i < $size; $i++) { 
    echo $mainArray[$i] . ' = ' . $circular[$i] . ', '; 
} 

Теперь выше код печатает это:

1 = A, 2 = B, 3 = C, UNDEFINED INDEX ERROR 

Что мне нужно, чтобы напечатать это:

1 = A, 2 = B, 3 = C, 4 = A, 5 = B, 6 = C, 7 = A, 8 = B, 9 = C, 10 = A 

Есть встроенный функция PHP, которая превращает массив в круглый массив? Я думаю, мне нужно использовать модульный оператор для этого.

ответ

18

Получить размер кругового массива ($circsize), а затем мода значение $i против него и использовать его в качестве индекса:

$mainArray = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 
$size  = count($mainArray); 
$circular = array('A', 'B', 'C'); 
$circsize = count($circular); 

for($i = 0; $i < $size; $i++) { 
    echo $mainArray[$i] . ' = ' . $circular[$i % $circsize] . ', '; 
} 
2

, пожалуйста, используйте остаток для кругового индекса массива:

$i2= $i % count($circular); 
echo $mainArray[$i] . ' = ' . $circular[$i2] . ', '; 

В качестве альтернативы вы можете использовать foreach для итерации по массивам и избегать использования арифметических вычислений для индекса:

reset($circular); 
foreach($mainArray as $item){ 
    echo $item . ' = ' . current($circular); 
    if(next($circular)===false) reset($circular); 
} 
6

Мне нравится Крис Уолш, но вот альтернатива, которая также работает для ассоциативных массивов (нецелые индексы). Может, вероятно, будет сокращен:

foreach($mainArray as $main) { 
    if(($circ = current($circular)) === false) { 
     $circ = reset($circular); 
    } 
    next($circular); 
    echo "$main=$circ "; 
} 

Если вам это нужно больше, чем один раз, может быть, функция:

function circular(&$array) { 
    if(($result = current($array)) === false) { 
     $result = reset($array); 
    } 
    next($array); 

    return $result; 
} 

Тогда просто использовать:

foreach($mainArray as $main) { 
    $circ = circular($circular); 
    echo "$main=$circ "; 
} 
+0

Это не будет работать, если значение элемента массива falsey. 'circ' будет возвращаться к началу массива всякий раз, когда он достигает этого элемента. – Barmar

+0

Спасибо. Отредактировано для проверки '=== false'. Таким образом, элемент массива может быть «ложным», но хорошо. – AbraCadaver

+0

Такое решение работает до тех пор, пока 'false' не является допустимым элементом массива. Решение с использованием модуля работает в более общем плане. – Barmar

1

Если вы используете PHP 5.5 или выше, то вы можете использовать php's generators и его ключевое слово yield:

function loopOnArrayFor($array, $limit = 1000) 
{ 
    for ($i = 0 ; $i <= count($array) ; $i++) { 
     if ($i == count($array)) { 
      if (--$limit > 0) { 
       $i = 0; 
      } else { 
       break; 
      } 
     } 
     yield $array[$i]; 
    } 
} 

Таким образом, этот метод будет зацикливаться на заданном массиве 1000 раз, если вы не передадите другое значение для аргумента $limit. здесь является случай использования:

foreach (loopOnArrayFor(['A','B','C'],5) as $v) { 
    echo "$v ,"; 
} 

что приводит следующий вывод:

A ,B ,C ,A ,B ,C ,A ,B ,C ,A ,B ,C ,A ,B ,C , 

Немного регулировка даст нам свой ожидаемый результат:

$counter = 1; 
foreach (loopOnArrayFor(['A','B','C'],5) as $v) { 
    echo $counter++ . ' = ' . $v .', ' ; 
} 

Что-то вроде:

1 = A, 2 = B, 3 = C, 4 = A, 5 = B, 6 = C, 7 = A, 8 = B, 9 = C, 10 = A, 11 = B, 12 = C, 13 = A, 14 = B, 15 = C, 

P. S.То, что вы ищете, может легко привести к исчерпанию памяти, поэтому, если вы можете, найти другое решение вместо того, чтобы полагаться на (контролируемый) бесконечный цикл :)

Смежные вопросы