簡體   English   中英

如何在不覆蓋 PHP 中現有鍵的情況下合並兩個多維數組?

[英]How to merge two multidimensional arrays without overwriting existing keys in PHP?

我正在嘗試添加兩個多維數組。 該函數應該與將數組加在一起完全相同,如下所示:$new_array = $array1 + $array2,除了它應該與多維數組一起使用。 這意味着 $array2 不應覆蓋現有的鍵值。

示例:假設我有以下 $default_array:

array
  'something' => int 0
  'nested' => 
    array (size=3)
      'a' => null
      'b' => null
      'c' => null

以及以下 $user_array:

array
  'something' => int 1000
  'nested' => 
    array (size=3)
      'a' => 1
  'new' => int 4

將兩者加在一起(如 $user_array + $default_array)應該給我:

array (size=4)
      'something' => int 1000
      'nested' => 
        array (size=3)
          'a' => 1
          'b' => null
          'c' => null
      'new' => int 4

目前,似乎如果我添加兩個多維數組,覆蓋功能似乎只適用於第一個數組維度。 這意味着在這種情況下,'nested' 已經存在於 $user_array 中,因此它不會附加其他值。

編輯:我還應該提到這需要使用無限數量的維度。

編輯 2:我只是嘗試應用 Rain 的答案,但它沒有按預期工作。 首先,我收到“未定義索引”通知。 其次,輸出不是我想要的。 考慮以下數組:

        $default = array(
            'a' => array(
                'a' => 'a',
                'b' => 'b',
                'c' => 'c',
                ),
            );

        $user = array(
            'b' => 1,
            'a' => array(
                'b' => 'something',
                'c' => 'something else',
                'd' => 'd',
                ),
            'c' => 2);

我用 Rain 的函數得到的輸出是這樣的:

array (size=3)
  'a' => 
    array (size=3)
      'a' => string 'a' (length=1)
      'b' => string 'b' (length=1)
      'c' => string 'c' (length=1)
  'b' => int 1
  'c' => int 2

在這個例子中,子數組中的 'b' 和 'c' 鍵應該分別是 'something' 和 'something else'。 我不太確定如何解決這個問題。

您可以嘗試使用array_merge_recursive() (不僅僅是 array_merge())http://www.php.net/manual/en/function.array-merge-recursive.php

<?php
$defaultarray = array(
'something' => 0,
  'nested' => 
    array (
      'a' => null,
      'b' => null,
      'c' => null));

$newArray = array(
  'something' => 1000, 
  'nested' => 
    array ('a' => 1,
  'new' => 4));

$mergedArray = array_merge_recursive($defaultarray, $newArray);
echo print_r($mergedArray,true);
?>

輸出:數組 ( [something] => Array ( [0] => 0 [1] => 1000 ) [嵌套] => Array ( [a] => Array ( [0] => [1] => 1 ) [b] => [c] => [新] => 4 ) )

遞歸函數絕對是這里的方法。 我只是提出了以下內容。 注意fill_in_aux的函數聲明中&的使用。 這會導致第二個參數(稱為$default )通過引用傳遞,而不是通過值傳遞。 它包含在fill_in因此不會修改真正的“默認”數組。

function fill_in($user, $default) {
    fill_in_aux($user, $default);
    return $default;
}

function fill_in_aux($user, &$default) {
    foreach ($user as $key => $value) {
        if (is_array($value)) {
            fill_in_aux($user[$key], $default[$key]);
        } else {
            $default[$key] = $value;
        }
    }
}

這個假設是在設置任何$default數組應該被任何存在於被覆蓋$user數組,即使在一個關鍵$user數組被設置為null 要更改此行為,請在fill_in_auxelse子句中添加另一個if語句。


示例用法

使用您的示例數組,輸出

print_r(fill_in($user_array, $default_array));

Array
(
    [something] => 1000
    [nested] => Array
        (
            [a] => 1
            [b] =>
            [c] =>
        )

    [new] => 4
)

分解

通常,在 PHP 中調用函數時,參數是按傳遞的:函數獲取傳入變量的副本 這意味着函數可以對參數做任何它想做的事情,但是當函數返回時,傳遞的原始變量不受影響。

當參數以&符號開頭時,參數通過引用傳遞,而不是被復制。 當函數對參數進行修改時,它實際上是直接對傳入的變量進行更改。

有關更多信息,請查看: http : //php.net/manual/en/language.references.pass.php

我很驚訝七年前沒有人向您提供原生函數array_replace_recursive() @bestprogrammerintheworld 在正確的軌道上,但選擇了錯誤的遞歸調用。

使用除此函數之外的任何內容都將導致不必要的代碼膨脹,並且很可能會導致性能下降。

代碼:(演示

var_export(
    array_replace_recursive($default, $user)
);

輸出:

array (
  'a' => 
  array (
    'a' => 'a',
    'b' => 'something',
    'c' => 'something else',
    'd' => 'd',
  ),
  'b' => 1,
  'c' => 2,
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM