12

I'm trying to edit an array on the fly, inside a foreach loop. I basically analyse each key, and if this key match the one I want, I want to add another entry in the array immediately after this one.

If I take this code,

$values = array(
    'foo' => 10,
    'bar' => 20,
    'baz' => 30
);

foreach($values as $key => $value){
    print $value . ' ';
    if($key == 'bar'){
        $values['qux'] = 21;
    }
}

I've got 2 problems,

  • first, the output is 10 20 30 instead of the expected 10 20 30 21
  • second, even if I solve the first problem, my value will still be added at the end of my array

How could I add the qux entry between bar and baz ones?

Thanks for your ideas.

Thilina Sampath
  • 3,615
  • 6
  • 39
  • 65
zessx
  • 68,042
  • 28
  • 135
  • 158
  • 1
    It's probably because you're not creating a new array, but use the old array to store the value in. That's why it's at the end of your array. To do what you want to do is to make a new variable let's say `$aData` and insert the values in there with your `foreach` loop. – Refilon Jan 29 '15 at 14:24
  • 1
    You don't need a second array to achieve this. Instead of `foreach` use a `for` loop and iterate through the length of the array and using the index variable of the for loop, add whatever you want to your array. – Vahid Amiri Sep 06 '16 at 18:26

4 Answers4

19

Foreach will not loop through new values added to the array while inside the loop.

If you want to add the new value between two existing values, you could use a second array:

$values = array(
    'foo' => 10,
    'bar' => 20,
    'baz' => 30
);
$newValues = array();
foreach($values as $key => $value) 
{
    $newValues[$key] = $value;
    if($key == 'bar') 
    {
        $newValues['qux'] = 21;
    }
}
print implode(' ', $newValue);

Also, see one of my favorite questions on StackOverflow discussing the foreach loop: How does PHP 'foreach' actually work?

Community
  • 1
  • 1
Lars Ebert
  • 3,487
  • 2
  • 24
  • 46
5

You can use the ampersand sign before the value.

//populate all the promos into their promoG groups
foreach($unclaimedPromoGroups as &$unclaimedPromoGroup) {
    $_promo = new Promo();
    $_promo->promoGroupID = $unclaimedPromoGroup['promo_groupID'];
    $promo = $_promo->getGroupPromos();
    $unclaimedPromoGroup["promos"] = $promo;
}
JJJ
  • 32,902
  • 20
  • 89
  • 102
Radiumrasheed
  • 103
  • 4
  • 7
2

For this you need to create a new array,

<?php
$values = array(
    'foo' => 10,
    'bar' => 20,
    'baz' => 30
);

$newarray = array();
foreach($values as $k => $v) 
{
    $newarray[$k] = $v;
    if($k == 'bar') 
        $newarray['qux'] = 21;
}

echo implode(' ', $newarray);

Demo:
http://3v4l.org/N4XgB

Parag Tyagi
  • 8,780
  • 3
  • 42
  • 47
1

The solution below uses the same array.

$values = array(
    'foo' => 10,
    'bar' => 20,
    'baz' => 30
);

function match($niddle, $haystack, $push, $offset = 0) {
    foreach(array_slice($haystack, $offset) as $key => $value) 
    {
        print $value . ' ';
        if($key == $niddle) 
        {
            $i = array_search($niddle, array_keys($haystack)) + 1;
            $haystack = array_slice($haystack, 0, $i, true) + $push + array_slice($haystack, $i, count($haystack) - $i, true);
            $haystack = match($niddle, $haystack, $push, $i);
            break;
        }
    }

    return $haystack;
}

$values = match('bar', $values, array('qux'=>21));

var_dump($values);
QHip
  • 11
  • 3