Reputation: 15660
I'm trying to loop through a multidimensional array, and add a new sub array. My code doesn't return any errors, but it also doesn't add the new item.
I have the following code:
foreach ($data['switches'] as $switch) {
foreach ($switch['atags'] as $attributelist) {
$nohardwareAttribFound = false;
foreach ($attributelist as $attribute) {
$pos = strpos(trim($attribute),'$attr_2_');
if ($pos !==false) {
//echo 'in the loop';
//found it. extract and exit loop
$modelnumber = substr(trim($attribute),8);
$hardwaremodel = array();
$hardwaremodel['tag'] = 'hardware_model:'.$modelnumber;
array_push($switch['atags'],$hardwaremodel);
print_r($switch);
//echo '<br>=====<br>';
$nohardwareAttribFound = true;
}
}//end foreach ($attributelist
}// end foreach ($switch['atags']
if ($nohardwareAttribFound==false) {
$hardwaremodel['tag'] = 'Unknown';
array_push($switch['atags'],$hardwaremodel);
}//end if
}// end foreach ($data['switches']
I would like the data to look like:
[atags] => Array (
[0] => Array ( [tag] => $id_365 )
[1] => Array ( [tag] => $typeid_8 )
[2] => Array ( [tag] => $any_object )
[3] => Array ( [tag] => $casd )
[4] => Array ( [tag] => $unmounted )
[5] => Array ( [tag] => $no_asset_tag )
[6] => Array ( [tag] => $attr_2_1086 )
[7] => Array ( [tag] => $untagged )
[8] => Array ( [tag] => hardware_model:1086 ) ) )
where the last array - element [8]
, represents a new subarray that I've added. The print_r()
statement looks correct, but when I loop through the results that are passed to my view, i can see that in fact, a new tag array has not been added.
Do i need to some sort of a replace instead of the array_push()
?
If it's not a good idea to modify an array while looping through it, could I simply check to see if an item exists.
how would i check if the ['atags'] array for each switch contains a [tag] with a value that looks like "$attr_2_NNNN" where N is a number? For example, check out element 6 in the sample array above. The challenge is that it's not always element 6, and you're not always guaranteed that a tag will have the attr_2 value.
I know there is an in_array()
function ... i will try something like:
if (in_array(array('$attr_2_'), $switches['atags']))
I have a bug with the logic around the $nohardwareAttribFound variable, which i'm going to fix.
Thanks
Upvotes: 1
Views: 175
Reputation: 28091
First of all: it is not advised to change an array or collection while you are iterating over it.
If you really want to do it like this, then you should take $switch
by reference instead of by value. Otherwise you can change $switch
to whatever you want, it will not be reflected in the $data['switches']
array.
To take $switch
by reference just add the &
:
foreach ($data['switches'] as &$switch) {
}
Check out foreach
in PHP manual.
EDIT After studying your code, I think this is what you are looking for:
foreach ($data['switches'] as &$switch) {
$hardwaremodel = array();
$hardwaremodel['tag'] = NULL; // initialize to NULL so we can check at the end of the loop if we have found a hardwaremodel or not (so we don't need that bool)
foreach ($switch['atags'] as $attributelist) {
foreach ($attributelist as $attribute) {
$pos = strpos(trim($attribute), '$attr_2_');
if ($pos !== false) {
$modelnumber = substr(trim($attribute), 8);
$hardwaremodel['tag'] = 'hardware_model:' . $modelnumber;
break;
}
}
if ($hardwaremodel['tag'] !== NULL)
break; // exit the loop because we already found a tag
}
if ($hardwaremodel['tag'] === NULL)
$hardwaremodel['tag'] = 'hardware_model:unknown';
// Note that this is a safe place to modify the $switch array
// as we are not currently iterating it
array_push($switch['atags'], $hardwaremodel);
}
Upvotes: 1
Reputation: 1219
I think you should replace
foreach ($data['switches'] as $switch)
with
foreach ($data['switches'] as &$switch)
Using a reference should do.
Note: use unset($switch) afterwards to destroy the reference.
Upvotes: 0
Reputation: 60413
Everytime you enter the loop your interation variable (ie. $switch
) is a copy - youre not modifying the original array $data
. To do that you need to modify the full path like:
array_push($data['switches']['atags'], $newVal)
Or you can pass by reference when you enter the loop like:
foreach ($data['switches'] as &$switch)
{
// ...
}
Upvotes: 0