我有两个数组。 第一个是结构,一个包含类别内所有元素的关联数组。类别的名称是此数组中的键。类别可以有不同的深度: 检查这个例子:
$structure = [
'fruits' => [
'sweet' => [
'red' => [
'watermelon' =>['id' => 1],
'cherry' =>['id' => 2],
'litchi' =>['id' => 3]
],
'white' => [
'coco' =>['id' => 13],
'lucuma' =>['id' => 14],
]
],
'sour' => [
'lemon' =>['id' => 4],
'orange' =>['id' => 5],
'tangerine' =>['id' => 6]
],
],
'colors' => [
'black' =>['id' => 7],
'green' =>['id' => 8],
'blue' => ['id' => 9]
],
'names' => [
'jack' =>['id' => 10],
'paul' =>['id' => 11],
'peter' =>['id' => 12]
]
];
我有第二个数组,包含我想要搜索的元素:
$results = ['coco', 'green','peter'];
我需要编写一个函数,为输出数组提供元素和它们所属的类别树。像这样:
$resultsInStructure = [
'fruits' => [
'sweet' => [
'white' => [
'coco' => ['id' => 13]
]
]
],
'colors' => [
'green' =>['id' => 8]
],
'names' => [
'peter' =>['id' => 12]
]
];
当然,函数需要递归。无论是走到第二个阵列的第一个,只是我无法做到正确......任何帮助都表示赞赏!
答案 0 :(得分:2)
试试这个
function walk($arr,$results)
{
if (is_array($arr))
{
$arrFound = [];
$arrTmpReturn = [];
foreach($arr AS $key => $val)
{
if (in_array($key, $results))
{
$arrFound = array_merge($arrFound,[$key => $val]);
}
$arrReturn = walk($val,$results);
if (!is_null($arrReturn))
{
$arrTmpReturn = array_merge($arrTmpReturn,[$key => $arrReturn]);
}
}
if (count($arrFound) > 0) return $arrFound;
if (count($arrTmpReturn) > 0) return $arrTmpReturn;
}
}
print_r(walk($structure,$results));
答案 1 :(得分:1)
您可以使用RecursiveIteratorIterator
遍历结构和引用,将值放到结果数组的正确位置:
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($structure),
RecursiveIteratorIterator::SELF_FIRST
);
$filters = array_flip($results);
$keys = [];
$resultsInStructure = [];
foreach ($iterator as $key => $value) {
if ($key === 'id') {
continue;
}
// Put key to the stack, so we can get the path of results.
$keys[$iterator->getDepth()] = $key;
if (!isset($filters[$key])) {
continue;
}
// Put the result in the right place in the tree structure.
$tmp =& $resultsInStructure;
foreach (array_slice($keys, 0, $iterator->getDepth()) as $_key) {
if (!isset($tmp[$_key])) {
$tmp[$_key] = [];
}
$tmp =& $tmp[$_key];
}
$tmp[$key] = $value;
}
这是working demo。