2011-12-05 67 views
2

給定一個數組,我想要一個數組鍵的扁平版本。每個數組鍵都需要該數組的「路徑」,並附加下劃線。PHP函數獲取遞歸路徑密鑰與路徑

一個例子最好地解釋了這一點。

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

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

答案函數將返回此:

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

UPDATE:

這裏正在進行的工作。它將接受一個數組並返回數組鍵,但沒有深度:

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)&& $ val)'而不是'if(is_array($ 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無法識別'葉子'。爲了使它與空的葉陣列一起工作,可以使用類似下面的類: 'class RecursiveArrayOnlyIterator extends RecursiveArrayIterator { public function hasChildren(){ return is_array($ this-> current())&&(count($這 - >電流())> 0); } }' 參考:[php.net](http://it1.php.net/manual/en/class.recursivearrayiterator.php) –

+0

@AntonioE。你也可以使用'RecursiveIteratorIterator :: SELF_FIRST' arg作爲RecursiveIteratorIterator構造函數(然後它將訪問所有節點,而不僅僅是樹葉)。但是,作爲結果,您將獲得許多部分路徑,而不是完整路徑。 – goat