2010-02-06 22 views
10

有沒有一種遞歸合併數組的方法,就像PHP的array_merge_recursive()函數一樣,除了整數鍵被視爲與字符串鍵相同?整數鍵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) 
    } 
} 

的思考?

回答

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)  
+1

雖然這是正確的,但感覺太過於人爲。爲什麼不是一個常規的循環呢? – Ezequiel 2012-07-24 12:48:30

3

我使用添加了一個字符串轉換鍵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 
//  ) 
// 
//) 
+1

您的'prefixer'和'unprefixer'函數需要驗證值是否爲數組!例如,在'prefixer'中,你需要'if(is_array($ v)) \t \t { \t \t \t $ out ['_'。 $ k] =前綴($ v); \t \t} \t \t其他 \t \t { \t \t \t $出[ '_'。$ k] = $ v; '在循環內部。否則它的工作很棒! – Link14 2015-01-02 23:28:43

0

如果你想的鑰匙,被作爲字符串處理,只是使它字符串時,你往裏面添加前綴,而不是用數字來填充它,然後重新填充另一個數組來訂購它。

0

這個遞歸數組合並函數不會重新編號整數鍵並將新值附加到現有值,或者如果該對不存在,則添加新的[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; 
    }