想象一下下面的多维数组:
$a = array(
'key' => 'hello',
'children' => array(
array(
'key' => 'sub-1'
),
array(
'key' => 'sub-2',
'children' => array(
array(
'key' => 'sub-sub-1'
)
)
)
)
);
我需要一个以递归方式运行这样一个数组的函数,然后最后使用粘合字符串返回某个子键的所有值的链。
function collectKeyChain(array $array, $key, $parentKey, $glue){
foreach($array as $k => $v){
if(is_array($v[$parentKey]))
$children=self::collectKeyChain($v[$parentKey], $key, $parentKey, $glue, $out);
$chain[]=$glue . implode($glue, $children);
}
return $chain;
}
这样叫:
collectValueChain($a, 'key', 'children', '/');
然后应该返回:
array(
'hello',
'hello/sub-1',
'hello/sub-2',
'hello/sub-2/sub-sub-1'
)
不幸的是,我的大脑似乎完全无法执行“嵌套思维”的任务。上面函数中提供的代码不起作用,仅仅因为它没有意义。我可以使用递归函数返回数组或字符串。但在最终输出中我需要一个数组。另一方面,我需要将元素链接在一起。
这就是两难选择。我头脑中唯一的解决方案是使用另一个参数,它通过引用传递,这是一个正在填充结果的数组。
像这样:
collectValueChain($a, 'key', 'children', '/', $arrayToBeFilledWithResults);
但是,如果不使用多个功能,我甚至无法完成这项工作。
也许它不能更容易地完成,但我仍然想知道。
答案 0 :(得分:1)
试试这个:
function collectKeyChain(array $array, $key, $parentKey, $glue) {
$return = array();
foreach ($array as $k => $v) {
if ($k == $key) {
$base = $v;
$return[] = $base;
} elseif ($k == $parentKey && is_array($v)) {
foreach ($v as $_v) {
$children = collectKeyChain($_v, $key, $parentKey, $glue);
foreach ($children as $child) {
$return[] = $base . $glue . $child;
}
}
}
}
return $return;
}
请注意,如果这是一个类中的静态方法,则必须将self ::添加到递归方法调用中。
答案 1 :(得分:1)
一个更简单的版本,没有很多foreach。考虑第二种方法:
collectValueChain($a, 'key', 'children', '/', $arrayToBeFilledWithResults);
我这样做:
function collectValueChain($a, $keyname, $parent, $glue, &$rtn, $pre="") {
$_pre = "";
if ($a[$keyname]) {
$rtn[] = $_pre = $pre.$glue.$a[$keyname];
}
if ($a[$parent]) {
if(is_array($a[$parent])) {
foreach($a[$parent] as $c)
collectValueChain($c, $keyname, $parent, $glue, $rtn, $_pre );
} else {
collectValueChain(a[$parent], $keyname, $parent, $glue, $rtn, $_pre );
}
}
$qtd = count($rtn);
return $rtn[-1];
}