简体   繁体   English

PHP - 意外的array_merge_recursive()输出

[英]PHP - Unexpected array_merge_recursive() output

I have this code 我有这个代码

$a1 = array(
    'success'    => TRUE,
    'data'       => array(
        'foo' =>
        array(
            21 =>
            array(
                1 =>
                array(1, 2, 3, 4, 5)
            )
        )
    )
);

$a2 = array(
    'success'    => TRUE,
    'data'       => array(
        'foo' =>
        array(
            21 =>
            array(
                7 =>
                array(6, 7, 8, 9, 10)
            )
        )
    )
);

$results = array();
$results = array_merge_recursive($results, $a1['data']);
$results = array_merge_recursive($results, $a2['data']);
var_dump($results);

From what I understood of array_merge_recursive(), I am expecting the results would be 根据我对array_merge_recursive()的理解,我期待结果

array
  'foo' => 
    array
      21 => 
        array
          1 => 
            array
              0 => int 1
              1 => int 2
              2 => int 3
              3 => int 4
              4 => int 5
           7 =>
              0 => int 6
              1 => int 7
              2 => int 8
              3 => int 9
              4 => int 10

Instead I get this 相反,我得到了这个

array
  'foo' => 
    array
      21 => 
        array
          1 => 
            array
              0 => int 1
              1 => int 2
              2 => int 3
              3 => int 4
              4 => int 5
      22 => 
        array
          7 => 
            array
              0 => int 6
              1 => int 7
              2 => int 8
              3 => int 9
              4 => int 10

Where did the 22 index come from? 22指数来自哪里? Why is it outputting differently? 为什么输出方式不同? Did I use the function wrong? 我使用的功能错了吗?

array_merge_recursive merges elements/arrays from the same depth as the first array, but if both arrays the key is a numerical index and they are the same it then appends to it. array_merge_recursive合并来自与第一个数组相同深度的元素/数组,但是如果两个数组的键都是数字索引并且它们是相同的,则它会附加到它。 This is what is happening in your situation. 这就是你的情况。 since then your array is appended at 2nd level where index 21 is found by creating index 22 . 从那时起你的阵列在其中index第二水平所附21是通过创建索引中找到22 To receive the desired output you have change your index 21 to a string key like "x21" 要接收所需的输出,您已将索引21更改为字符串键,如"x21"

Notes from php manual php手册中的注释

If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. 如果输入数组具有相同的字符串键,则这些键的值将合并到一个数组中,这是递归完成的,因此如果其中一个值是数组本身,则该函数会将其与相应的条目合并在另一个数组中。 If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended. 但是,如果数组具有相同的数字键,则后面的值不会覆盖原始值,但会附加。

I just came across the same issue, I wanted to merge the arrays but surprisingly found the keys were changed automatically in the result. 我刚刚遇到同样的问题,我想合并数组,但令人惊讶地发现键在结果中自动更改。 The reason was because my "keys" are string of decimal numbers, without any alphabetic characters. 原因是因为我的“键”是十进制数字串,没有任何字母字符。

But luckily I noticed that if the keys have alphabetic characters, they could be reserved. 但幸运的是,我注意到如果键有字母字符,它们可以保留。 So just came up with the following idea, which would append a letter 'S' to each key recursively before the merge, and later remove it in the final result. 因此,我想出了以下想法,它将在合并之前递归地向每个键附加一个字母'S',然后在最终结果中将其删除。

Please refer to the enhanced_array_merge_recursive function for details: 有关详细信息,请参阅enhanced_array_merge_recursive函数:

<?php

$aa = [
  '10' => 'book',
  '14' => ['cat'],
];

$ab = [
  '12' => 'cd',
  '18' => 'cup',
  '14' => ['dog'],
];

var_dump(enhanced_array_merge_recursive($aa, $ab));

function revise_keys($source)
{
    if (!is_array($source)) {
        return $source;
    }

    $target = [];

    foreach ($source as $key => $value) {
        $target['S' . $key] = revise_keys($value);
    }

    return $target;
}

function revert_keys($source)
{
    if (!is_array($source)) {
        return $source;
    }

    $target = [];

    foreach ($source as $key => $value) {
        $target[substr($key, 1 - strlen($key))] = revert_keys($value);
    }

    return $target;
}

function enhanced_array_merge_recursive(...$candidates)
{
    $merged = [];

    foreach ($candidates as $candidate) {
        if (!is_array($candidate)) {
            continue;
        }

        $merged = array_merge_recursive($merged, revise_keys($candidate));
    }

    return revert_keys($merged);
}

Output looks like following: 输出如下:

array(4) {
  [10] =>
  string(4) "book"
  [14] =>
  array(1) {
    [0] =>
    array(2) {
      [0] =>
      string(3) "cat"
      [1] =>
      string(3) "dog"
    }
  }
  [12] =>
  string(2) "cd"
  [18] =>
  string(3) "cup"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM