如何在array_reduce中改变这个数组

时间:2019-05-23 23:53:07

标签: php

有没有一种方法可以在PHP中使用array_reduce来改变数组?

我正在尝试做这样的事情:

给出一些id的有序列表:

$array = [["id" => 1], ["id" => 13], ["id" => 4]];

还有一棵树,其子树与相应的id s相匹配:

$tree = [
  "id" => 2334,
  "children" => [
    [
      "id" => 111,
      "children" => []
    ],
    [
      "id" => 1, // <- this is a match
      "children" => [
        [
          "id" => 13, // <- this is a match
          "children" => [
            [
              "id" => 4, // <- this is a match
              "children" => []
            ],
            [
              "id" => 225893,
              "children" => []
            ],
            [
              "id" => 225902,
              "children" => []
            ]
          ]
        ]
      ]
    ]
  ]
];

如何修改该子树中的数组?

我目前正在尝试使用array_reduce沿着树走下来并对其进行变异。但是,此突变不会应用于最初传入的$tree

array_reduce($array, function (&$acc, $item) {
  $index = array_search($item['id'], array_column($acc['children'], 'id'));
  $acc['children'][$index]['mutated'] = true; // mutation here
  return $acc['children'][$index];
}, $tree);

echo "<pre>";
var_dump($tree); // $tree is unchanged here
echo "</pre>";

$tree上方运行后,为什么array_reduce没有发生突变?

在这种情况下是否可以使用foreach

1 个答案:

答案 0 :(得分:1)

我认为此功能可以完成您想要的操作。它向下递归$tree,查找id中的$array值,并为这些孩子设置mutation标志:

function mutate(&$tree, $array) {
    if (in_array($tree['id'], array_column($array, 'id'))) {
        $tree['mutated'] = true;
    }
    foreach ($tree['children'] as &$child) {
        mutate($child, $array);
    }
}
mutate($tree, $array);
var_export($tree);

输出:

array (
  'id' => 2334,
  'children' => array (
    0 => array (
      'id' => 111,
      'children' => array ( ),
    ),
    1 => array (
      'id' => 1,
      'children' => array (
        0 => array (
          'id' => 13,
          'children' => array (
            0 => array (
              'id' => 4,
              'children' => array ( ),
              'mutated' => true,
            ),
            1 => array (
              'id' => 225893,
              'children' => array ( ),
            ),
            2 => array (
              'id' => 225902,
              'children' => array ( ),
            ),
          ),
          'mutated' => true,
        ),
      ),
      'mutated' => true,
    ), 
  ), 
)

Demo on 3v4l.org