2012-10-04 97 views
18

如何對多維關聯數組進行深度擴展(用於解碼的JSON對象)。 我需要PHP的等效jQuery's $.extend(true, array1, array2)數組而不是JSON和PHP。PHP深度擴展陣列

這裏是什麼,我需要一個例子(array_merge_recursive似乎並沒有做同樣的事情)

$array1 = ('1'=> ('a'=>'array1a', 'b'=>'array1b')); 
$array2 = ('1'=> ('a'=>'array2a', 'c'=>'array2b')); 

$array3 = array_extend($array1, $array2); 

//$array3 = ('1'=> ('a'=>'array2a', 'b'=>'array1b', 'c'=>'array2b')) 

注意覆蓋如何數組2陣列1,如果有相同的值(如類的擴展是如何工作的)

+0

爲什麼不array_merge? – Dev

+2

如果你有PHP 5.3.0+,你可以使用['array_replace_recursive'](http://www.php.net/manual/en/function.array-replace-recursive.php),它完全符合你的需求。 – Sathvik

+0

我還沒有時間回顧所有的答案,但array_replace_recursive絕對看起來像是最簡單的方法來完成這一點。想把它寫成答案,我會接受嗎? –

回答

18

如果你有PHP 5.3.0+,你可以用它array_replace_recursive不正是你需要的:

array_replace_recursive()具有相同 值從所有替代陣列1的值以下數組。如果第二個數組中存在第一個數組 的密鑰,則其值將由第二個數組中的值 替代。如果密鑰存在於第二個數組中,而不是第一個,它將在第一個數組中創建。如果第一個數組中只有一個鍵 ,它將保持原樣。如果幾個陣列 通過替換,它們將按順序處理,後面的 陣列覆蓋以前的值。

1

array_merge文檔摘自:

function array_extend($a, $b) { 
    foreach($b as $k=>$v) { 
     if(is_array($v)) { 
      if(!isset($a[$k])) { 
       $a[$k] = $v; 
      } else { 
       $a[$k] = array_extend($a[$k], $v); 
      } 
     } else { 
      $a[$k] = $v; 
     } 
    } 
    return $a; 
} 
+4

這應該是維基文章 –

+0

@Mihai Iorga快速問題你怎麼做一個維基文章??? – Baba

+1

@Baba編輯/發佈時,您可以在某處查看「社區」。 – Yoshi

0

隨着一點點的谷歌搜索,我發現這個:

/** 
* jquery style extend, merges arrays (without errors if the passed values are not arrays) 
* 
* @return array $extended 
**/ 
function extend() { 
    $args = func_get_args(); 
    $extended = array(); 
    if(is_array($args) && count($args)) { 
     foreach($args as $array) { 
      if(is_array($array)) { 
       $extended = array_merge($extended, $array); 
      } 
     } 
    } 
    return $extended; 
} 

extend($defaults, $new_options); 
1

這可能是你在找什麼:

function array_extend(&$result) { 
    if (!is_array($result)) { 
    $result = array(); 
    } 

    $args = func_get_args(); 

    for ($i = 1; $i < count($args); $i++) { 
    // we only work on array parameters: 
    if (!is_array($args[$i])) continue; 

    // extend current result: 
    foreach ($args[$i] as $k => $v) { 
     if (!isset($result[$k])) { 
     $result[$k] = $v; 
     } 
     else { 
     if (is_array($result[$k]) && is_array($v)) { 
      array_extend($result[$k], $v); 
     } 
     else { 
      $result[$k] = $v; 
     } 
     } 
    } 
    } 

    return $result; 
} 

用法:

$arr1 = array('a' => 1, 'b' => 2, 'c' => 3); 
$arr2 = array('b' => 'b', 'd' => 'd'); 
array_extend($arr1, $arr2); 
print_r($arr1); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd') 

// or, to create a new array and leave $arr1 unchanged use: 
array_extend($arr3, $arr1, $arr2); 
print_r($arr3); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd') 

// or, use the return value: 
print_r(array_extend($arr1, $arr2)); // but this will also modify $arr1 
0

我猜這裏是正確的答案,這是因爲:

  • 你的答案有警告的錯誤:

    警告:由於$ a不總是一個數組無法使用標量值作爲數組中......

,並使用$ A [$ K]。

  • array_merge_recursive確實合併數組,但是將其轉換值具有重複鍵陣列而不是覆蓋與所述第二陣列中的重複的值的第一陣列中的值,如array_merge一樣。

  • 其他aswers不是遞歸或不簡單。

所以,這裏是我的回答:你的答案沒有錯誤:

function array_extend(array $a, array $b) { 
    foreach($b as $k=>$v) { 
     if(is_array($v)) { 
      if(!isset($a[$k])) { 
       $a[$k] = $v; 
      } else { 
       if(!is_array($a[$k]){ 
        $a[$k]=array(); 
       } 
       $a[$k] = array_extend($a[$k], $v); 
      } 
     } else { 
      $a[$k] = $v; 
     } 
    } 
    return $a; 
} 

我與三元運算符回答:

function array_extend(array $a, array $b){ 
    foreach($b as $k=>$v) 
      $a[$k] = is_array($v)&&isset($a[$k])? 
       array_extend(is_array($a[$k])? 
         $a[$k]:array(),$v): 
       $v; 
    return $a; 
} 

編輯:和獎金,一個與許多陣列你想要:

function array_extend(){ 
    $args = func_get_args(); 
    while($extended = array_shift($args)) 
      if(is_array($extended)) 
        break; 
    if(!is_array($extended)) 
      return FALSE; 
    while($array = array_shift($args)){ 
     if(is_array($array)) 
       foreach($array as $k=>$v) 
         $extended[$k] = is_array($v)&&isset($extended[$k])? 
          array_extend(is_array($extended[$k])? 
            $extended[$k]:array(),$v): 
          $v; 
    } 
    return $extended; 
} 
2

我在相同的地方使用它我使用angular.extend(dst,src)和jQuery.extend()。

function extend($base = array(), $replacements = array()) { 
    $base = ! is_array($base) ? array() : $base; 
    $replacements = ! is_array($replacements) ? array() : $replacements; 

    return array_replace_recursive($base, $replacements); 
} 

實施例:

SI()是一個實用的sanitize函數,抓住$ _POST或$ _GET和返回一個數組。

 $s = extend(array(
      'page' => 1, 
      'take' => 100, 
      'completed' => 1, 
      'incomplete' => 1, 
     ), si()); 
1

你應該使用:https://github.com/appcia/webwork/blob/master/lib/Appcia/Webwork/Storage/Config.php#L64

/** 
* Merge two arrays recursive 
* 
* Overwrite values with associative keys 
* Append values with integer keys 
* 
* @param array $arr1 First array 
* @param array $arr2 Second array 
* 
* @return array 
*/ 
public static function merge(array $arr1, array $arr2) 
{ 
    if (empty($arr1)) { 
     return $arr2; 
    } else if (empty($arr2)) { 
     return $arr1; 
    } 

    foreach ($arr2 as $key => $value) { 
     if (is_int($key)) { 
      $arr1[] = $value; 
     } elseif (is_array($arr2[$key])) { 
      if (!isset($arr1[$key])) { 
       $arr1[$key] = array(); 
      } 

      if (is_int($key)) { 
       $arr1[] = static::merge($arr1[$key], $value); 
      } else { 
       $arr1[$key] = static::merge($arr1[$key], $value); 
      } 
     } else { 
      $arr1[$key] = $value; 
     } 
    } 

    return $arr1; 
}