【问题标题】:PHP—array_merge_recursive() - no Array for same keysPHP—array_merge_recursive() - 相同键没有数组
【发布时间】:2017-03-13 09:39:36
【问题描述】:
$php -a
php > $data1 = ['tag' => 'div', 'classes' => [1,2,3]];
php > $data2 = ['tag' => 'section', 'classes' => [2,3,4,5,6]];
php > $result = array_merge_recursive($data1, $data2);
php > print_r($result);
Array
(
    [tag] => Array
        (
            [0] => div
            [1] => section
        )

    [classes] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 2
            [4] => 3
            [5] => 4
            [6] => 5
            [7] => 6
        )

 )

Docs中所述:

如果输入数组具有相同的字符串键,则这些键的值将合并到一个数组中[…]

PHP 中是否有一个现有的函数基本上做同样的事情,但没有将相同的键合并到一个数组中,以便覆盖值并保留键?

在这种情况下,我希望得到这样的结果:

Array
(
    [tag] => section

    [classes] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [5] => 4
            [6] => 5
            [7] => 6
        )

 )

关于@JustOnUnderMillions 的评论:

是的,我想知道,这不是我对这样一个函数的期望,我希望得到我正在寻找的结果。

【问题讨论】:

  • 如果这些值被覆盖,那么您的结果将是$data2
  • 对于classes 键中的数组:如果覆盖值并保留键 那么您将无法获得这样的结果([0] => 1 [1] => 2 [2] => 3 [5] => 4 [6] => 5 [7] => 6),它'将是( [0] => 2 [1] => 3 [2] => 4 [3] => 5 [4] => 6 )
  • 你需要递归合并吗?
  • 是的,这很重要
  • 请注意:没有人想知道为什么该函数不创建像[['tag']=>['div','section'],'classes'=>[[1,2,3],[/*...*/]]] 这样的数组吗?这对于 php 来说很典型,它会合并到 vlaues 到一个数组中,但是如果你首先有数组,它们将被合并在一起?!?假设第二个有'classes'=>'string' 字符串将被合并到给定的第一个数组中。所以现在关于更多的子数组(rekursive!!)。那是怎么工作的......我不明白,所以我尽量不使用它。

标签: php arrays merge


【解决方案1】:

你可以处理这个函数(递归和多数组):

<?php

$data1 = ['tag' => 'div', 'classes' => [1,2,3], 'foo' => ['bar' => [1,2], 'bar2' => 'foo']];
$data2 = ['tag' => 'section', 'classes' => [2,3,4,5,6], 'foo' => ['bar' => [2,3], 'bar3' => 'foo']];
$data3 = ['tag' => 'section', 'classes' => [7], 'foo' => ['bar' => [5], 'bar3' => 'foo2']];


print_r(custom_array_merge($data1, $data2, $data3));

function custom_array_merge() {
    $arguments = func_get_args();
    $datas = call_user_func_array('array_merge', $arguments);
    foreach($datas as $key => $value) {
        if(is_array($value)) {
            $values = [];
            foreach($arguments as $array) {
                $values[] = isset($array[$key]) ? $array[$key] : [];
            }

            if(array_depth($value) === 1) {
                $datas[$key] = array_unique(call_user_func_array('array_merge', $values));
            }else {
                $datas[$key] = call_user_func_array('custom_array_merge', $values);
            }
        }
    }

    return $datas;
}

function array_depth(array $array) {
    $max_depth = 1;

    foreach ($array as $value) {
        if (is_array($value)) {
            $depth = array_depth($value) + 1;

            if ($depth > $max_depth) {
                $max_depth = $depth;
            }
        }
    }

    return $max_depth;
}

【讨论】:

  • 你为什么使用call_user_function而不是像custom_array_merge(…)这样的直接函数调用?
  • 因为你想处理多个数组作为输入
  • 啊,明白了……call_user_func_array,借口……像Javascript Function.prototype.apply()
【解决方案2】:

要获得您需要的结果,请使用:

function my_array_merge_recursive($array1,$array2){
   foreach($array1 as $key=>&$val){
       if(!isset($array2[$key])){
           contiune;
       }
       if(is_array($val)){
           $val = array_unique(array_merge($val,$array2[$key]));
       } else {
           $val=$array2[$key];
       }
       unset($array2[$key]);
   }
   #if we have entries left in second array
   if(count($array2)){
       return array_merge($array1,$array2);
   }
   return $array1;
}
$data1 = ['tag' => 'div', 'classes' => [1,2,3]];
$data2 = ['tag' => 'section', 'classes' => [2,3,4,5,6]];
$result = my_array_merge_recursive($data1, $data2);
print_r($result);

此功能仅适用于这种特殊情况。

【讨论】:

  • 不是递归的,只能处理两个数组作为输入。
  • @philipp 请再次阅读答案的最后一行,谢谢。如果你问我:我想要那个结果——你希望数组以一种非常特殊的方式合并。 php 中没有可以为您执行此操作的函数。构建你自己的,也许使用这个版本作为起点。
猜你喜欢
  • 2011-01-04
  • 1970-01-01
  • 2012-08-16
  • 2015-05-29
  • 2011-01-13
  • 2015-01-04
  • 2014-03-12
  • 2015-02-01
  • 1970-01-01
相关资源
最近更新 更多