2011-12-05 68 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