使用已知的父键将静态关联元素推送到已知级别的所有子数组中

Push a static associative element into all subarrays on a known level with a known parent key

提问人:Adrien Hingert 提问时间:11/16/2023 最后编辑:mickmackusaAdrien Hingert 更新时间:11/21/2023 访问量:74

问:

我有一个动态生成的PHP多维数组,如下所示:

Array (
    [uid_1] => Array (
        [sub_1] => Array (
            [sub_sub_1] => Array (
                [id1] => "val_1",
                [id2] => "val_2"
            )
        )
        [sub_2] => Array (
            [sub_sub_1] => Array (
                [id1] => "val_1",
                [id2] => "val_2"
            ),
            [sub_sub_2] => Array (
                [id3] => "val_3",
                [id4] => "val_4"
            )
        )
    )
)

数组要大得多,将包含多个 [uid]、[sub] 和 [sub_sub]。
请注意,虽然 [uid] 和 [sub] 是唯一的,但 [sub_sub] 不是。

是否可以在不使用循环且不知道 [uid_1] 和 [sub_2] 的值的情况下将 [id5] => “val_5” 添加到 [sub_sub_1] 的所有实例中?

php 多维 数组

评论

1赞 ADyson 11/16/2023
使用循环有什么问题?

答:

0赞 Jenson M John 11/16/2023 #1

由于您提到数组要大得多,因此可能需要 Loop。

    <?php
    $mainArray = array (
        "uid_1" => array (
            "sub_1" => array (
                "sub_sub_1" => array (
                    "id1" => "val_1",
                    "id2" => "val_2"
                )
                ),
            "sub_2" => array (
                "sub_sub_1" => array (
                    "id1" => "val_1",
                    "id2" => "val_2"
                ),
                "sub_sub_2" => array (
                    "id3" => "val_3",
                    "id4" => "val_4"
                )
            )
        )
    );

    echo "<pre>";
    print_r( $mainArray );
    echo "</pre>";



    foreach($mainArray["uid_1"] as $key=>$val){
        
        //$val (Arrays with index 'sub_1', 'sub_2' etc.)
        //Get array with index 'sub_sub_1' & Assign a New Value with key `id5`.

        $mainArray["uid_1"][$key]['sub_sub_1']["id5"] = "val_5";


    }

    echo "<pre>";
    print_r( $mainArray );
    echo "</pre>";
    ?>
2赞 Ishtiaq Ahmed 11/16/2023 #2

请尝试以下代码。

<?php
$mainArray = array(
    "uid_1" => array(
        "sub_1" => array(
            "sub_sub_1" => array(
                "id1" => "val_1",
                "id2" => "val_2"
            )
        ),
        "sub_2" => array(
            "sub_sub_1" => array(
                "id1" => "val_1",
                "id2" => "val_2"
            ),
            "sub_sub_2" => array(
                "id3" => "val_3",
                "id4" => "val_4"
            )
        )
    )
);

echo "<pre>";
print_r($mainArray);
echo "</pre>";

foreach ($mainArray["uid_1"] as $key => $val) {

    // Check if 'sub_sub_1' exists before trying to access it
    if (isset($mainArray["uid_1"][$key]['sub_sub_1'])) {
        // Get array with index 'sub_sub_1' & Assign a New Value with key `id5`.
        $mainArray["uid_1"][$key]['sub_sub_1']["id5"] = "val_5";
    }
}

echo "<pre>";
print_r($mainArray);
echo "</pre>";
?>

评论

0赞 mickmackusa 11/21/2023
这不太可能是一个完全实现的解决方案,因为您正在对访问进行硬编码 -- 这实际上应该是另一个。Asker 说道:uid_1foreach()without knowing the value of [uid_1] and [sub_2]
1赞 lukas.j 11/16/2023 #3
$array = [
  'uid_1' => [
    'sub_1' => [
      'sub_sub_1' => [ 'id1' => 'val_1', 'id2' => 'val_2' ]
    ],
    'sub_2' => [
      'sub_sub_1' => [ 'id1' => 'val_1', 'id2' => 'val_2' ],
      'sub_sub_2' => [ 'id3' => 'val_3', 'id4' => 'val_4' ]
    ]
  ],
  'uid_2' => [
    'sub_1' => [
      'sub_sub_1' => [ 'id1' => 'val_1', 'id3' => 'val_3' ]
    ],
  ]
];

$iterator = new RecursiveIteratorIterator(
  new RecursiveArrayIterator($array),
  RecursiveIteratorIterator::SELF_FIRST
);
$iterator->setMaxDepth(2);

while ($it->valid()) {
  if ($it->key() === 'sub_sub_1') {
    $array[$it->getSubIterator(0)->key()][$it->getSubIterator(1)->key()]['sub_sub_1']['id5'] = 'val_5';
  }
  $it->next();
}

print_r($array);

输出:

Array
(
    [uid_1] => Array
        (
            [sub_1] => Array
                (
                    [sub_sub_1] => Array
                        (
                            [id1] => val_1
                            [id2] => val_2
                            [id5] => val_5
                        )

                )

            [sub_2] => Array
                (
                    [sub_sub_1] => Array
                        (
                            [id1] => val_1
                            [id2] => val_2
                            [id5] => val_5
                        )

                    [sub_sub_2] => Array
                        (
                            [id3] => val_3
                            [id4] => val_4
                        )

                )

        )

    [uid_2] => Array
        (
            [sub_1] => Array
                (
                    [sub_sub_1] => Array
                        (
                            [id1] => val_1
                            [id3] => val_3
                            [id5] => val_5
                        )

                )

        )

)

笔记:

访问阵列的每个顶部节点。包装 和 将访问数组的每个节点,而不仅仅是顶部节点。并确保我们不会浪费时间访问超过三级深度的节点。RecursiveArrayIteratorRecursiveIteratorIteratorRecursiveArrayIteratorsetMaxDepth

我们进行迭代,检查键是否为“sub_sub_1”,如果为 true,则通过调用获取父路径部分。然后我们只需创建键并赋值。getSubIterator->key

0赞 mickmackusa 11/21/2023 #4

不要费心试图让一个简单的任务变得更加复杂。使用函数进行迭代可能需要更长的时间,并且更难理解。

使用两个嵌套循环,通过引用修改数据集,并在需要时无条件推送所需的关联元素。

即使数据集(子数组)没有级别,此脚本也会创建级别并安全地将所需元素推送到其中。如果这不是所需的行为,则应提供更具代表性的示例输入数组,并表达应如何处理此边缘情况。sub_sub_1

代码:(演示)

foreach ($array as &$uids) {
    foreach ($uids as &$subs) {
        $subs['sub_sub_1']['id5'] = 'val_5';
    }
}
var_export($array);

输出:

array (
  'uid_1' => 
  array (
    'sub_1' => 
    array (
      'sub_sub_1' => 
      array (
        'id1' => 'val_1',
        'id2' => 'val_2',
        'id5' => 'val_5',
      ),
    ),
    'sub_2' => 
    array (
      'sub_sub_1' => 
      array (
        'id1' => 'val_1',
        'id2' => 'val_2',
        'id5' => 'val_5',
      ),
      'sub_sub_2' => 
      array (
        'id3' => 'val_3',
        'id4' => 'val_4',
      ),
    ),
  ),
  'uid_2' => 
  array (
    'sub_1' => 
    array (
      'sub_sub_1' => 
      array (
        'id1' => 'val_1',
        'id3' => 'val_3',
        'id5' => 'val_5',
      ),
    ),
  ),
)