1

我正在尝试遍历一个多维数组,并添加一个新的子数组。我的代码没有返回任何错误,但也没有添加新项目。

我有以下代码:

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']

我希望数据看起来像:

[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 ) ) ) 

其中最后一个数组 - element[8]代表我添加的一个新子数组。该print_r()语句看起来是正确的,但是当我遍历传递给我的视图的结果时,我可以看到实际上并没有添加一个新的标签数组。

我需要某种替换而不是替换array_push()吗?

如果在循环遍历数组时修改数组不是一个好主意,我可以简单地检查一个项目是否存在。我将如何检查每个开关的 ['atags'] 数组是否包含一个 [tag],其值​​看起来像“$attr_2_NNNN”,其中 N 是一个数字?例如,检查上面示例数组中的元素 6。挑战在于它并不总是元素 6,并且您并不总是保证标签将具有 attr_2 值。我知道有一个in_array()功能......我会尝试类似的东西:

if (in_array(array('$attr_2_'), $switches['atags']))

我对 $nohardwareAttribFound 变量的逻辑有一个错误,我将对其进行修复。
谢谢

4

3 回答 3

1

首先:不建议在迭代时更改数组或集合。

如果您真的想这样做,那么您应该$switch按引用而不是按值获取。否则您可以更改$switch为您想要的任何内容,它不会反映在$data['switches']数组中。

要作为$switch参考,只需添加&

foreach ($data['switches'] as &$switch) { 
}

查看foreachPHP 手册

编辑在研究了您的代码之后,我认为这就是您要寻找的内容:

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); 
}
于 2012-08-17T17:44:51.420 回答
0

每次进入循环时,您的交互变量(即$switch)都是一个副本 - 您没有修改原始数组$data。为此,您需要修改完整路径,例如:

array_push($data['switches']['atags'], $newVal)

或者您可以在进入循环时通过引用传递,例如:

foreach ($data['switches'] as &$switch) 
{
   // ... 
}
于 2012-08-17T17:45:06.837 回答
0

我认为你应该更换

foreach ($data['switches'] as $switch) 

foreach ($data['switches'] as &$switch) 

使用参考应该可以。

注意:之后使用 unset($switch) 来销毁引用。

于 2012-08-17T17:45:32.240 回答