2017-04-26 157 views
0

我有這三個數組:陣列合併以相同的密鑰

Array 
(
    [1] => [email protected] 
    [2] => [email protected] 
    [3] => [email protected] 
) 

Array 
(
    [1] => 
    [2] => 4234235 
    [3] => 
) 

Array 
(
    [2] => 1 
) 

我想產生這樣的輸出:

Array 
(
    [1] => array(
      [0] => [email protected] 
      ) 
    [2] => array(
      [0] => [email protected] 
      [1] => 4234235 
      [2] => 1 
      ) 
    [3] => array(
      [0] => [email protected] 
      ) 
) 

我需要一些幫助,因爲我已經研究array_merge_recursive()array_merge(),但我無法得到正確的結果。

如果我需要使用foreach()我必須做些什麼來合併這3個數組。

回答

4

寫了一個小腳本:

$a = array 
(
    1=>"[email protected]", 
    2=>"[email protected]", 
    3=>"[email protected]", 
); 

$b = array 
(
    2 => 4234235 
); 

$c = array 
(
    2 => 1 
); 

$arrayKeys = array_unique(
    array_merge(
     array_keys($a), 
     array_keys($b), 
     array_keys($c) 
    ) 
); 

$d = array_combine(
    $arrayKeys, 
    array_fill(
     0, 
     count($arrayKeys), 
     array() 
    ) 
); 

foreach($a as $key => $value) { 
    if(!empty($a[$key])) { 
     $d[$key][] = $a[$key]; 
    } 
    if(!empty($b[$key])) { 
     $d[$key][] = $b[$key]; 
    } 
    if(!empty($c[$key])) { 
     $d[$key][] = $c[$key]; 
    } 
} 
var_dump($d); 

此外,如果你願意,你可以使用變量名稱僅

//names of the variables to merge together 
$arrayVariableNames = array("a","b","c"); 

//merging array keys together 
$arrayKeys = array(); 
foreach($arrayVariableNames as $variableName) { 
    $arrayKeys = array_merge(
     $arrayKeys, 
     array_keys(${$variableName}) 
    ); 
} 
$arrayKeys = array_unique($arrayKeys); 

//initialize the result array with empty arrays 
$resultArray = array_combine(
    $arrayKeys, 
    array_fill(
     0, 
     count($arrayKeys), 
     array() 
    ) 
); 

//loop through all the keys and add the elements from all the arrays 
foreach($resultArray as $key => &$value) { 
    foreach($arrayVariableNames as $variableName) { 
     if(!empty(${$variableName}[$key])) { 
      $value[] = ${$variableName}[$key]; 
     } 
    } 
} 
+0

如果'$ b'或'$ c'數組的值比'$ a'數組多? – Bhaskar

+0

編輯所以現在沒關係 –

1

至於你有沒有懷疑發現,array_merge_recursive()固執地搗毀所有合併的陣列一起數字或「數字字符串」鍵轉換爲一維數組。爲了避免這種行爲,您需要將每個數組的初始鍵作爲字符串轉換,而不會被假定爲array_merge_recursive()的數字。

此外,你想篩選出所有具有空值的元素。

我最初編寫了一個單線程,執行關鍵重新鑄造然後過濾值,但效率不那麼高。對於您的情況,您應該只在可能有包含空值的陣列上使用array_filter()

輸入數組:

$a=[1=>"[email protected]",2=>"[email protected]",3=>"[email protected]"]; 
$b=[1=>"",2=>"4234235",3=>""]; 
$c=[2=>1]; 

代碼:

// remove empty values from all arrays that may have them 
$b=array_filter($b,'strlen'); 

// for all arrays, cast numeric keys to string by prepending with a space 
function addK($v){return " $v";} 
$a=array_combine(array_map('addK',array_keys($a)),$a); 
$b=array_combine(array_map('addK',array_keys($b)),$b); 
$c=array_combine(array_map('addK',array_keys($c)),$c); 

// merge arrays recursively 
$merged=array_merge_recursive($a,$b,$c); 

// cast keys back to numeric 
$merged=array_combine(array_map('trim',array_keys($merged)),$merged); 

// force all top-level elements to be arrays 
foreach($merged as $k=>$v){ 
    if(is_string($merged[$k])){$merged[$k]=[$v];} 
} 

var_export($merged); 

輸出:

array (
    1 => array (
     0 => '[email protected]', 
    ), 
    2 => array (
     0 => '[email protected]', 
     1 => '4234235', 
     2 => 1, 
    ), 
    3 => array (
     0 => '[email protected]', 
    ), 
) 

對於誰想要知道其中的差別讀者當array_merge_recursive()運行沒有準備:

array (
    0 => '[email protected]', 
    1 => '[email protected]', 
    2 => '[email protected]', 
    3 => '', 
    4 => '4234235', 
    5 => '', 
    6 => 1, 
) 

注意1d數組和重新索引的鍵?對OP來說完全沒用。

最後,對於任何想要將所有數組的鍵重新投射並想讓我的過程更加乾燥的人,可能有機會設置可變參數函數或類似函數。我只是懶得去追求這個概念,因爲我不想讓自己的答案變得更復雜,也不是可怕的重複自己。

+0

我很喜歡katona.abel的方法,它們很聰明。雖然有幾點不同。第一種方法賦予了數組'$ a'的循環權限,然後OP發表評論,要求提供一種新的方法,允許$ b和$ c中有更多的元素。第二種方法(我不太喜歡它,但它確實使用變量來完成'array_merge_recursive()'的設計目的。我跑了一些測試,並且katona的第二種方法似乎沒有突破 - 好的編碼!如果任何人都可以找到我們的任何方法的缺陷,請給我們留言。 – mickmackusa

相關問題