Ravi
Ravi

Reputation: 195

PHP - replace values in sub array

I have two arrays $pq and $rs. please see them below:

$pq = array ('page-0'=>array ('line-0'=>array('item-0'=>array('name'=>"item-00",'value'=>"123"),
                                           'item-1'=>array('name'=>"item-01",'value'=>"456")
                                            ),
                            'line-1'=>array('item-0'=>array('name'=>"item-10",'value'=>"789"),
                                           'item-1'=>array('name'=>"item-11",'value'=>"012")
                                            )),

'page-1'=>array ('line-0'=>array('item-0'=>array('name'=>"item-100",'value'=>"345"),
                                           'item-1'=>array('name'=>"item-101",'value'=>"678")
                                            ),
                            'line-1'=>array('item-0'=>array('name'=>"item-110",'value'=>"901"),
                                           'item-1'=>array('name'=>"item-111",'value'=>"234")
                                            ),
                            'line-2'=>array('item-0'=>array('name'=>"item-210",'value'=>"567"),
                                           'item-1'=>array('name'=>"item-211",'value'=>"890")
                                            ))

);

 $rs = array ('1'=>array('name'=>'item-00', 'value'=>"abc"),
'2'=>array('name'=>'item-01', 'value'=>"def"),
'3'=>array('name'=>'item-10', 'value'=>"ghi"),
'4'=>array('name'=>'item-11', 'value'=>"jkl"),
'5'=>array('name'=>'item-100', 'value'=>"mno"),
'6'=>array('name'=>'item-101', 'value'=>"pqr"),
'7'=>array('name'=>'item-110', 'value'=>"stu"),
'8'=>array('name'=>'item-111', 'value'=>"vwx")
);

What I am trying to do is to replace the values in $pq for items with the values from $rs. for example item-01 in $pa to be replaced with abc from $rs. What I tried is this:

foreach($rs as &$rs1) {
echo "first count :".$firstCount."<br>";
foreach($pq as $pages) {
    foreach($pages as $lines) {
        foreach($lines as &$item) {
            if ($item['name'] == $rs1['name']) { echo "matching </p>";
                    $item['value']=$rs1['value'];
                echo '<pre>';
                print_r($item);
                echo '</pre>';
                echo "<hr>";
                }


            }
       }

    }
}

When I print the values of $item from $pq, it prints the values from $rs, but when I print the whole array $pq, the values seem to be unchanged. Can anyone please help me find out what I am missing ?

Upvotes: 0

Views: 2503

Answers (3)

Ja͢ck
Ja͢ck

Reputation: 173642

You can build a search array first so that you can match items easier:

$search = array_reduce($rs, function(&$prev, $current) {
    $prev[$current['name']] = $current;
    return $prev;
}, []);

This creates another array with the item name as the key. Then, you iterate over each item in $pq and modify the leaves where necessary:

foreach ($pq as &$page_data) {
  foreach ($page_data as &$line_data) {
    foreach ($line_data as &$item_data) {
      if (isset($search[$item_data['name']])) {
        $item_data = $search[$item_data['name']];
      }
    }
  }
}

Make sure to use references at each level of iteration.

Upvotes: 1

Sharanya Dutta
Sharanya Dutta

Reputation: 4021

You’ve assigned $item by reference but haven’t done the same for $pages and $lines. There will be no effect on the actual values of $pq unless you assign $pages by reference; similarly, the actual values of $pages will remain unchanged unless you assign $lines by reference. Therefore, in order to achieve what you want, change foreach($pq as $pages) to foreach($pq as &$pages) and foreach($pages as $lines) to foreach($pages as &$lines).

Upvotes: 1

sgress454
sgress454

Reputation: 24958

You're correctly looping through the items in each line by reference, but you're not doing it for the lines or pages themselves. So you're updating the value of an item in a copy of the line, instead of the line itself. It should be:

foreach($rs as $rs1) {
    echo "first count :".$firstCount."<br>";
    foreach($pq as &$pages) {
        foreach($pages as &$lines) {
            foreach($lines as &$item) {
                if ($item['name'] == $rs1['name']) { echo "matching </p>";
                        $item['value']=$rs1['value'];
                    echo '<pre>';
                    print_r($item);
                    echo '</pre>';
                    echo "<hr>";
                } 

            }
       }

    }
}

Note that the & in front of &$lines and &$pages. Note also that $rs1 doesn't need to be passed by reference, since you aren't changing anything in that array.

Upvotes: 1

Related Questions