【问题标题】:PHP's array_merge_recursive behaviour on integer keys整数键上的 PHP array_merge_recursive 行为
【发布时间】:2011-01-13 20:45:03
【问题描述】:

有没有一种递归合并数组的方法,就像 PHP 的 array_merge_recursive() 函数一样,除了整数键被视为与字符串键相同?

(对于这个过程来说,关键是保持可解析为整数的过程很重要。)

例如:

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

将合并"a" 键并按预期输出以下内容:

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

但是,当使用整数作为键时(即使作为字符串):

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

array_merge_recursive() 将返回:

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

而不是非常想要的:

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

想法?

【问题讨论】:

    标签: php arrays multidimensional-array


    【解决方案1】:

    我正在使用 soulmerge 通过添加字符串来转换键的想法。但是,我的新函数只能处理 2 个参数,但你就是这种情况,所以我就是这样做的。看看吧。

    // 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;
    }
    

    样本数据是什么样的?

    // 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
    //         )
    // 
    // )
    

    让我们试一试:

    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
    //         )
    // 
    // )
    

    【讨论】:

    • 您的prefixerunprefixer 函数需要验证该值是否为数组!例如,在prefixer 中,您需要在循环中包含if (is_array($v)) { $out['_' . $k] = prefixer($v); } else { $out['_' . $k] = $v; }。否则它工作得很好!
    【解决方案2】:

    您可以在数组键前面加上一个短字符串:

    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)     
    

    【讨论】:

    • 虽然这是正确的,但感觉太做作了。为什么不使用常规循环呢?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      此递归数组合并函数不会重新编号整数键并将新值附加到现有键或添加新的 [key => value] 对(如果该对不存在)。我想并且可以肯定,这个功能就是你所需要的。

      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;
          }
      

      【讨论】:

        猜你喜欢
        • 2012-08-16
        • 2011-01-04
        • 1970-01-01
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多