2010-09-17 63 views
2

我有一個從YAML反序列化的表單數據的多維數組。因此,它看起來是這樣的:遞歸合併數組而不覆蓋重複鍵的最佳方式

Array(
    'name' => 'Somone', 
    'email' => '[email protected]', 
    'billing' => Array(
    'address_1' => '1234 Somewhere' 
    'address_2' => NULL, 
    'city' => 'Somewhere', 
    'state' => 'ST' 
    'country' => 'CO' 
    'postal_code' => '12345' 
    ), 
    'shipping' => Array(
    'address_1' => '1234 Somewhere' 
    'address_2' => NULL, 
    'city' => 'Somewhere', 
    'state' => 'ST' 
    'country' => 'CO' 
    'postal_code' => '12345' 
) 
); 

什麼,我需要做的就是擊敗這個這樣我就可以輸出一些CSV,所以它應該是這個樣子:

Array(
    'name' => 'Somone', 
    'email' => '[email protected]', 
    'billing_address_1' => '1234 Somewhere' 
    'billing_address_2' => NULL, 
    'billing_city' => 'Somewhere', 
    'billing_state' => 'ST' 
    'billing_country' => 'CO' 
    'billing_postal_code' => '12345' 
    'shipping_address_1' => '1234 Somewhere' 
    'shipping_address_2' => NULL, 
    'shipping_city' => 'Somewhere', 
    'shipping_state' => 'ST' 
    'shipping_country' => 'CO' 
    'shipping_postal_code' => '12345' 
); 

我永遠不會知道確定陣列/散列有多深 - 它只有兩層,如圖所示,或者它可以是5.

這也是在Symfony 1.4中,所以如果需要的話,sfForm及其所有的奢侈品都是可用的。我認爲應該有一個明智的方式來使用小部件模式和小部件來做到這一點。但是,如果可能的話,我想避免將數據綁定到表單。這不是實際表單提交過程的一部分,但在管理員下載提交數據集的操作中完全分開。

回答

2

只是一個快餐式技巧,但它的工作原理相當不錯:

function array_flatten($array, $prefix = '') { 
    $newArray = array(); 
    foreach($array as $key => $value) { 
     if(is_array($value)) { 
       $newArray = array_merge($newArray, array_flatten($value, $key)); 
     } 
     else { 
       $index = empty($prefix) ? $key : $prefix.'_'.$key; 
       $newArray[$index] = $value; 
      } 
    } 
    return $newArray; 
} 

測試:

$a = array(
     "a" => "b", 
     "ca" => array(
      "de" => "ef", 
      "ef" => "gd" 
     ) 
); 

var_dump(array_flatten($a)); 

// Output: 
/* 

array(3) { 
    ["a"]=> 
    string(1) "b" 
    ["ca_de"]=> 
    string(2) "ef" 
    ["ca_ef"]=> 
    string(2) "gd" 
} 

*/ 
1

這個怎麼樣?我不知道你想如何處理重複鍵,所以我把這個選項留給了你。只需用您自己的代碼替換; // Do something here on duplicate key即可。

$info = Array(
    'name' => 'Someone', 
    'email' => '[email protected]', 
    'billing' => Array(
     'address_1' => '1234 Somewhere', 
     'address_2' => NULL, 
     'city' => 'Somewhere', 
     'state' => 'ST', 
     'country' => 'CO', 
     'postal_code' => '12345' 
    ), 
    'shipping' => Array(
     'address_1' => '1234 Somewhere', 
     'address_2' => NULL, 
     'city' => 'Somewhere', 
     'state' => 'ST', 
     'country' => 'CO', 
     'postal_code' => '12345' 
    ) 
); 

function explodeArray($array, &$data, $prefix = "") { 
    foreach ($array as $key => $value) { 
     if (is_array($value)) { 
      explodeArray($value, $data, $prefix . $key . "_"); 
     } else { 
      if (!array_key_exists($prefix . $key, $data)) { 
       $data[$prefix . $key] = $value; 
      } else { 
       ; // Do something here on duplicate key 
      } 
     } 
    } 
} 

$result = array(); 
explodeArray($info, $result); 

print_r($result); 
2
function flatten(Array $array, $name = '') { 
    $ret = array(); 

    foreach ($array as $key => $value) { 
     $itemname = ($name ? $name . '_' : '') . $key; 

     if (is_array($value)) { 
      $ret = array_merge($ret, flatten($value, $itemname)); 
     } else { 
      $ret[$itemname] = $value; 
     } 
    } 

    return $ret; 
}