2011-12-05 10 views
2

配列を与えられた場合、配列キーのフラット化バージョンが必要です。各配列キーには、そのポイントにアンダースコアを付加した配列の 'パス'が必要です。パスで再帰的パスキーを取得するPHP関数

この例では、このベストを説明しています。

array("location","details_width","details_height","details_level_three"); 

がUPDATE:ここ

は進行中の作業である

$arr = array("location"=>0,"details"=>array("width"=>0,"height"=>0,"level"=>array("three"=>0))); 

function answer($arr) {....} 

応答機能は、これを返します。それは無い深さではなく、配列を受け入れ、配列のキーを返します。ここ

function recursive_keys($input) 
{ 
    $output = array_keys($input); 
    foreach($input as $sub){ 
     if(is_array($sub)){ 
      $output = array_merge($output, recursive_keys($sub)); 
     } 
    } 
    return $output; 
} 
+0

、すべての配列キーを返します。しかし、私は現在の 'パス'をどのように追加するのか分かりません。 – user1082428

+0

あなたの不成功の試みをよく見せてください – zerkms

+0

元のコメントが更新されました。 – user1082428

答えて

2
function recursive_keys(array $array, array $path = array()) { 
    $result = array(); 
    foreach ($array as $key => $val) { 
     $currentPath = array_merge($path, array($key)); 
     if (is_array($val)) { 
      $result = array_merge($result, recursive_keys($val, $currentPath)); 
     } else { 
      $result[] = join('_', $currentPath); 
     } 
    } 
    return $result; 
} 

デモ:私は成功した多次元配列を横切ることができる関数のセットを持っているhttp://codepad.viper-7.com/WQ3UYI

+0

優秀、これは私が必要なものです!あなたのコードには、if(!is_array($ val))行の直前にif(!is_array($ val))を追加しました。値が配列の場合はキーを追加しません。 – user1082428

+0

私のケースで動作させるには、 'if(is_array($ val))'の代わりに 'if(is_array($ val)&& $ val)'を使用してください。 –

7
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); 
$results = array(); 
foreach ($ritit as $leafValue) { 
    $path = array(); 
    foreach (range(0, $ritit->getDepth()) as $depth) { 
     $path[] = $ritit->getSubIterator($depth)->key(); 
    } 
    $results[] = join('_', $path); 
} 
+2

+1ほとんど書かれていない機能をうまく使います。 :) – deceze

+0

+1もし、空の配列を扱っているのであれば、このソリューションは完全ではありません。なぜなら、RecursiveArrayIteratorは 'leaves'を認識できないからです。空の葉配列を使用するには、次のようなクラスを使用できます。 'class RecursiveArrayOnlyIterator extends RecursiveArrayIterator { public function hasChildren(){ return is_array($ this-> current())&&(count($) this-> current())> 0); } } リファレンス:[php.net](http://it1.php.net/manual/en/class.recursivearrayiterator.php) –

+0

@AntonioE。 RecursiveIteratorIteratorコンストラクタに対して 'RecursiveIteratorIterator :: SELF_FIRST' argを使用することもできます(それだけでなく、すべてのノードを参照します)。しかし、結果として多くの部分的な、完全なパスよりも少なくなるでしょう。 – goat