PHP поиск многомерного массива по значению со случайным массивом подуровня - PullRequest
0 голосов
/ 30 апреля 2020

Можно ли искать многомерный массив неизвестной глубины по значению?

Например, с помощью:

$data = [
    [
        'uid' => '100',
        'name' => 'MAIN',
        [
            'uid' => '2222',
            'name' => 'SUB_MAIN',
            [
                'uid' => '8524',
                'name' => 'SUB_SUB_MAIN',
            ]
        ]
    ],
    [
        'uid' => '5465',
        'name' => 'MAIN',
    ],
    [
        'uid' => '40489',
        'name' => 'MAIN',
    ]
];

Я хочу найти путь к подмассиву, где uid равно 8524.

При использовании указанного массива результат должен быть: [0, 0, 0].

1 Ответ

0 голосов
/ 30 апреля 2020

В качестве отправной точки можно использовать следующее:

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', 'On');

function findPath(array $items, callable $criteria, array $path = []): array {
    foreach ($items as $key => $item) {
        if (!is_array($item)) {
            continue;
        }

        // prepare path to this item
        $pathToHere = array_merge($path, [$key]);

        // if the items fits the criteria
        if ($criteria($item)) {
            // return it's path
            return $pathToHere;
        }

        // otherwise check children
        $pathToChild = findPath($item, $criteria, $pathToHere);

        // and if return value is not empty
        if (count($pathToChild) > 0) {
            // return path to child
            return $pathToChild;
        }
    }

    // base case if no item matches
    return [];
}


$data = [
    [
        'uid' => '5465',
        'name' => 'MAIN',
    ],
    [
        'uid' => '100',
        'name' => 'MAIN',
        [
            'uid' => '2222',
            'name' => 'SUB_MAIN',
            [
                'uid' => '8524',
                'name' => 'SUB_SUB_MAIN',
                [
                    'uid' => 'X',
                    'name' => 'Y',
                ]
            ],
            [
                'uid' => '8524_test',
                'name' => 'SUB_SUB_MAIN_test',
                [
                    'uid' => '8524_test_sub',
                    'name' => 'SUB_SUB_MAIN_test_sub',
                ]
            ]
        ]
    ],
    [
        'uid' => '40489',
        'name' => 'MAIN',
    ]
];

$path = findPath($data, fn(array $item): bool => $item['uid'] === '8524_test_sub');

print_r($path);

/*
    Array
    (
        [0] => 1
        [1] => 0
        [2] => 1
        [3] => 0
    )
*/

Демонстрация: https://3v4l.org/XKTH8

Примечание приведенный выше код требует php 7.4, но только из-за конструкции fn() => .... Это может быть просто заменено любым другим подходящим callable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...