简体   繁体   English

PHP 在 integer 键上的 array_merge_recursive 行为

[英]PHP's array_merge_recursive behaviour on integer keys

Is there an approach for recursively merging arrays, in the same way as PHP's array_merge_recursive() function does, except that integer keys are treated the same as string keys?有没有一种递归合并 arrays 的方法,就像 PHP 的array_merge_recursive() function 一样,除了Z157DB7DF530023575515D366C9B 键被视为相同的字符串键672?

(It's important for the process that the keys remain parse-able as integers.) (对于这个过程来说,关键是保持可解析为整数的过程很重要。)

For example:例如:

$a = array(
    'a' => array(1)
);
$b = array(
    'a' => array(2, 3)
);
var_dump(array_merge_recursive($a, $b));

Will merge the on the "a" key and output, as expected, the following:"a"键和output合并,如预期的那样,如下:

array(1) {
    ["a"] => array(3) {
        [0] => int(1)
        [1] => int(2)
        [2] => int(3)
    }
}

However, when using integers for keys (even when as a string):但是,当使用整数作为键时(即使作为字符串):

$a = array(
    '123' => array(1)
);
$b = array(
    '123' => array(2, 3)
);
var_dump(array_merge_recursive($a, $b));

array_merge_recursive() will return: array_merge_recursive()将返回:

array(2) {
    [0] => array(3) {
        [0] => int(1)
    }
    [1] => array(2) {
        [0] => int(2)
        [1] => int(3)
    }
}

Instead of the much desired:而不是非常需要的:

array(1) {
    ["123"] => array(3) {
        [0] => int(1)
        [1] => int(2)
        [2] => int(3)
    }
}

Thoughts?想法?

I'm using soulmerge's idea of converting the keys by adding a string. 我正在使用soulmerge通过添加字符串来转换键的想法。 My new function can only handle 2 parameters, however, but that was the case you had, so that's what I went with. 然而,我的新功能只能处理2个参数,但这就是你的情况,所以这就是我的用途。 Have a look. 看一看。

// Adds a _ to top level keys of an array
function prefixer($array) {
    $out = array();
    foreach($array as $k => $v) {
        $out['_' . $k] = $v;
    }
    return $out;
}
// Remove first character from all keys of an array
function unprefixer($array) {
    $out = array();
    foreach($array as $k => $v) {
        $newkey = substr($k,1);
        $out[$newkey] = $v;
    }
    return $out;
}
// Combine 2 arrays and preserve the keys
function array_merge_recursive_improved($a, $b) {
    $a = prefixer($a);
    $b = prefixer($b);
    $out = unprefixer(array_merge_recursive($a, $b));
    return $out;
}

And what's out sample data look like? 样本数据是什么样的?

// some sample data    
$a = array(
    '123' => array(1)
);
$b = array(
    '123' => array(2, 3)
);

// what do the results say:    
print_r($a);
// Array
// (
//     [123] => Array
//         (
//             [0] => 1
//         )
// 
// )

print_r($b);
// Array
// (
//     [123] => Array
//         (
//             [0] => 2
//             [1] => 3
//         )
// 
// )

And let's try them out: 让我们尝试一下:

print_r(array_merge_recursive($a, $b));
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//         )
// 
//     [1] => Array
//         (
//             [0] => 2
//             [1] => 3
//         )
// 
// )

print_r(array_merge_recursive_improved($a, $b));
// Array
// (
//     [123] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//         )
// 
// )

you can prefix the array keys with a short string: 您可以使用短字符串为数组键添加前缀:

function addPrefix($a) {
    return '_' . $a;
}
# transform keys
$array1 = array_combine(array_map('addPrefix', array_keys($array1)), $array1);
$array2 = array_combine(array_map('addPrefix', array_keys($array2)), $array2);
# call array_combine
$array = array_merge_recursive($array1, $array2);
# reverse previous operation  
function stripPrefix($a) {
     return substr($a, 1);
}
$array = array_combine(array_map('stripPrefix', array_keys($array)), $array)     

如果您希望将键视为字符串,只需在填充时添加前缀,而不是用数字填充它,然后重新填充另一个数组以便对其进行排序。

This recursive array merge function doesn't renumber integer keys and appends new values to existing ones OR adds a new [key => value] pair if the pair doesn't exist. 此递归数组合并函数不重新编号整数键并将新值附加到现有键或如果该对不存在则添加新的[key => value]对。 I suppose and exen sure, that this function is that what you need. 我想并且确定,这个功能就是你所需要的。

function array_merge_recursive_adv(array &$array1, $array2) {
        if(!empty($array2) && is_array($array2))
            foreach ($array2 as $key => $value) {
                    if(array_key_exists($key,$array1)) {
                        if(is_array($value)){
                            array_merge_recursive_adv($array1[$key], $value);
                        } else {
                             if(!empty($array1[$key])) {
                                if(is_array($array1[$key])){
                                    array_push($array1[$key], $value);
                                } else {
                                    $array1[$key] = [$array1[$key]];
                                    $array1[$key][] = $value;
                                }
                             } else if(empty($array1[$key])) {
                                $array1[$key] = $value;
                             }
                        }
                    } else {
                        $array1[$key] = $value;
                    }
            }
            return $array1;
    }

array_merge_recursive() simply isn't the right tool for merging two 2d array with numeric first level keys. array_merge_recursive()根本不是将两个二维数组与数字一级键合并的正确工具。

Use a standard loop to merge the second array's values into the first array on the related first level key.使用标准循环将第二个数组的值合并到相关第一级键的第一个数组中。

Code: ( Demo )代码:(演示

foreach ($b as $k => $v) {
    $a[$k] = array_merge($a[$k] ?? [], $v);
}
var_export($a);

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

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