2009-12-10 5 views
8

は、例えば配列です:PHPはネストされた配列をキーを連結しながら単一の配列に変換しますか?ここ

$foo = array(
      'employer' => array(
        'name' => 'Foobar Inc', 
        'phone' => '555-555-5555' 
        ), 
      'employee' => array(
        'name' => 'John Doe', 
        'phone' => '555-555-5556', 
        'address' => array(
          'state' => 'California', 
          'zip' => '90210' 
         ) 
        ), 
      'modified' => '2009-12-01', 
     ); 

そして、私はこのような結果を取得したいと思い:

$fooCompressed = array(
      'employer_name' => 'Foobar Inc', 
      'employer_phone' => '555-555-5555', 
      'employee_name' => 'John Doe', 
      'employee_phone' => '555-555-5556' 
      'employee_address_state' => 'California', 
      'employee_address_zip' => '90210', 
      'modified' => '2009-12-01' 
      ) 

は、どのように私はこれを処理する再帰関数を書くことについては行くだろうか?

答えて

13

このような何か:私は、数回の反復後

function flatten_array($array, $prefix = null) { 
    if ($prefix) $prefix .= '_'; 

    $items = array(); 

    foreach ($array as $key => $value) { 
    if (is_array($value)) 
     $items = array_merge($items, flatten_array($value, $prefix . $key)); 
    else 
     $items[$prefix . $key] = $value; 
    } 

    return $items; 
} 
+0

+1これは私がやるだろうものにかなり近いです。キーは変更されているので、それを行う組み込み関数はなく、配列でもあるサブ値をドリルダウンするには再帰が必要です。 – zombat

+0

良い例。私は出力配列を参照渡しという考えが好きです。 – GSto

3

ここでは、二番目のパラメータを経由して、トップレベルの接頭辞を指定することができる機能ですスタックベースのアプローチを使用して再帰を回避し、少し単純化するこの問題に対する解決策を洗練させることができました。

/*** 
* @name array_flatten 
* @author Tom Penzer @tpenzer 
* Flattens a multi-tiered array into a single-tiered 
* associative array with keys reflective of their 
* values' hierarchy. 
* 
* @param array $array  Required - the multi- 
* level keyed array to be flattened 
* @param string $separator Optional - the string 
* used to separate the keys from different levels of 
* the hierarchy 
* 
* @return array a single-level keyed array 
***/ 
function array_flatten($array, $separator = '_') { 
    $output = array(); 

    while (list($key, $value) = each($array)) { 
     if (is_array($value)) { 
      $build = array(); 
      foreach ($value as $s_key => $s_value) { 
       $build[$key . $separator . $s_key] = $s_value; 
      } 
      unset($array[$key]); 
      $array = $build + $array; 
      unset($build); 
      continue;//skip write to $output 
     } 
     $output[$key] = $value; 
     unset($array[$key]); 
    } 

    return $output; 
} 

正確にはメソッドが要求されていませんが、問題の再帰的アプローチとは対照的です。あなたstr_replaceは、URLエンコードされた値を使用している場合は、私が使用してこの「トリック」はhttp_build_queryだと思う

0
/** 
* Flatten a multi-dimensional array or a nested object, constructing concatenated keys for 
* nested elements. 
* @param array or object $array - the array or object to be flattened 
* @param array or string $key_path - current parent keys path. 
* Pass this parameter as string if you need to set a common prefix for all keys 
* @param string $level_separator - keys concatenation glue 
* @param array $flat - resulting flattened array (omit this parameter when calling the function) 
* @return single-dimensional array with all array keys as concatenated keys of elements' 
* paths through the data structure 
*/ 
function flattenArray($array, &$key_path = array(), $level_separator = '.', &$flat = array()) 
{ 
     if(!is_array($key_path)) 
     { 
      // sanitize key_path 
      $key_path = array((string)$key_path); 
     } 
     foreach($array as $key => $value) 
     { 
      // push current key to path 
      array_push($key_path, $key); 

      if(is_array($value) || is_object($value)) 
      { 
       // next level recursion 
       $flat = array_merge($flat, flattenArray($value, $key_path, $level_separator, $flat)); 
      } 
      else 
      { 
        // write the value directly 
        $flat[implode($level_separator, $key_path)] = $value; 
       } 

       // remove used key 
       array_pop($key_path); 
     } 

     return $flat; 
    } 
0

function makeNonNestedRecursive(array &$out, $key, array $in){ 
    foreach($in as $k=>$v){ 
     if(is_array($v)){ 
      makeNonNestedRecursive($out, $key . $k . '_', $v); 
     }else{ 
      $out[$key . $k] = $v; 
     } 
    } 
} 

function makeNonNested(array $in){ 
    $out = array(); 
    makeNonNestedRecursive($out, '', $in); 
    return $out; 
} 

// Example 
$fooCompressed = makeNonNested($foo); 
3

は/アウト再帰(あるいは少なくともPHPはあなたのためにそれを行うせる)コードの

3行ワット目障りの小さいです以下のために[と]

$string  = http_build_query($array); 
$string  = urldecode($string); 
$string  = str_replace(
        array('[',']'), 
        array('_','') , 
        $string 
       ); 
parse_str($string, $flat_array); 

$ flat_arrayは次のようになります。

array(7) { 
    ["employer_name"]   =>"Foobar Inc" 
    ["employer_phone"]  =>"555-555-5555" 
    ["employee_name"]   =>"John Doe" 
    ["employee_phone"]  =>"555-555-5556" 
    ["employee_address_state"]=>"California" 
    ["employee_address_zip"] =>"90210" 
    ["modified"]    =>"2009-12-01" 
} 
関連する問題