选择元素时,将数组视为圆形数组 - PHP

I have an array on which I loop over. I have another array from which I need to select one by one but it needs to go on circle in case it gets to the end of the array. To make it clear here is some code:

$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] . ', ';
}

Now above code prints this:

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

What I need it to print is this:

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

Is there a built in function to PHP that turns an array into circular array? I think I need to use modular operator to achieve this.

Get the size of the circular array ($circsize)and then mod the value $i against it and use that as your index:

$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] . ', ';
}

please use remainder for the circular array index:

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

As an alternate, you can use foreach to iterate through arrays and avoid using arithmetic calculations for the index:

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

I like Chris Walsh's but here is an alternate that also works for associative arrays (non-integer indexes). Could probably be shortened:

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

If you need this more than once, maybe a function:

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

    return $result;
}

Then just use:

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

If you are using PHP 5.5 or above, then you could take advantage of php's generators and its yield keyword:

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];
    }
}

So this method will loop on the given array for 1000 times unless you pass another value for the $limit argument. here is the use case:

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

which results in the following output:

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

A little adjustment will give us your expected result:

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

Something like:

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. What you are seeking, can easily lead to memory exhaustion so if you can, find another solution instead of being relied on a (controlled) infinite loop :)