如果另一个数组

时间:2017-06-08 09:55:37

标签: php arrays recursion associative-array

我有两个数组。 第一个是结构,一个包含类别内所有元素的关联数组。类别的名称是此数组中的键。类别可以有不同的深度: 检查这个例子:

$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]
            ]
        ];

当然,函数需要递归。无论是走到第二个阵列的第一个,只是我无法做到正确......任何帮助都表示赞赏!

2 个答案:

答案 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