У меня есть массив, содержащий информацию о пространстве имен:

$array = [
    ['App', 'Classes', 'Auth'],
    ['App', 'Classes', 'Auth'],
    ['App', 'Classes', 'Middleware'],
    ['App', 'Classes', 'Phone'],
    ['App', 'Classes', 'Auth'],
    ['App', 'Mail'],
    ['App', 'Mail', 'Sender'],
    ['App', 'Box'],
];

Теперь я хочу создать один массив или объект, который должен отображать информацию о пространстве имен в иерархическом порядке:

$result = [
    ['App' => 
        ['Classes' => 
            [
                'Auth',
                'Middleware',
                'Phone',
            ]
        ],
        ['Mail' => 
            ['Sender']
        ],
        ['Box'] => []
    ]
]

Я пробовал некоторые рекурсивные функции, но все, что я получаю, это плоский массив ...


private function createNamespaceHirachy( $namespaces ) {


        foreach ($namespaces as $index => $namespace) {
            $namespaces[$namespace] = [];
            $namespaces[$namespace] = $this->createNamespaceHirachy($namespaces[$namespace]);
        }


    return $namespaces;
}

Извините, это может быть намного проще, но я просто схожу с ума: - /

-3
DaFunkyAlex 27 Май 2019 в 15:32

2 ответа

Лучший ответ
<?php

$array = [
    ['App', 'Classes', 'Auth'],
    ['App', 'Classes', 'Auth'],
    ['App', 'Classes', 'Middleware'],
    ['App', 'Classes', 'Phone'],
    ['App', 'Classes', 'Auth'],
    ['App', 'Mail'],
    ['App', 'Mail', 'Sender'],
    ['App', 'Box'],
];

$hierarchy = [];

foreach($array as $each_data){
    $curr_hierarchy = &$hierarchy;
    foreach($each_data as $each_namespace){
        if(!isset($curr_hierarchy[$each_namespace])){
            $curr_hierarchy[$each_namespace] = [];
        }

        $curr_hierarchy = &$curr_hierarchy[$each_namespace];
    }
}

print_r($hierarchy);

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

  • Мы перебираем все иерархические данные в $array по очереди.
  • Мы инициализируем окончательный результирующий массив как $hierarchy в приведенном выше коде.
  • Теперь, внутри внутреннего цикла foreach, мы поддерживаем текущий этап иерархии. Другими словами, $curr_hierarchy содержит текущий уровень, на котором мы находимся.
  • По мере того как мы зацикливаемся внутри внутреннего цикла foreach, если текущий этап не имеет пространства имен в качестве ключа, мы назначаем его и продвигаемся на один уровень дальше, передавая его в качестве новой текущей иерархии.
  • Обратите внимание, что передача по ссылке & необходима для отражения общих изменений в массиве, в противном случае создается новый клон, сохраняющий ваш окончательный массив пустым.
  • Вы также можете заметить, что сами дочерние элементы также являются массивом. Я думаю, что это хорошо для вашего текущего контекста, но дайте мне знать, если это не то, что вы хотели.
2
vivek_23 27 Май 2019 в 12:49

Вот фрагмент для вашего сценария

$results = json_decode(json_encode($array)); // converting to object to play
$tree    = null;
foreach ($results as $result) {
    // checking first getting address of it to play
    $thisref                          = &$refs->{$result[0]}; 
    $tree->{$result[0]}               = &$thisref;
    // checking for level 1 if not empty
    $thisref                          = &$refs->{$result[1]};
    $tree->{$result[0]}->{$result[1]} = &$thisref;
    // checking for level 2 if not empty
    if (!empty($result[2])) {
        $thisref                                        = &$refs->{$result[2]};
        $refs->{$result[0]}->{$result[1]}[] = $result[2];//&$thisref;
        $refs->{$result[0]}->{$result[1]} = array_unique($refs->{$result[0]}->{$result[1]});
    }

}
// finally converting back to array
print_r(json_decode(json_encode($tree), true));

Рабочая демонстрация .

1
Rahul 27 Май 2019 в 12:50