Создание древовидной структуры массива PHP из динамического набора данных

У меня есть история с возникают проблемы с деревом, и я сделал много исследование на тема. Думаю, я забиваю этот гвоздь не тем молотком.

Я пытаюсь создать набор данных древовидной иерархии из массива, но не только из массива, в котором определены родительско-дочерние отношения. Это в значительной степени сравнение одного массива в наборе данных с другим, а затем объединение того же самого и разветвление различий в новый массив.

Причина этого заключается в поиске в наборах данных позже (таких как ACL), которые, как ожидается, будут большие, и в возврате этого формата через вызовы API.

Исходя из запроса PHP и MySQL, я возвращаю массив, который выглядит следующим образом (пары значений ключа могут быть любыми, это просто обобщение):

$testArray = array(
    array('group' => 'Group1','group_id' => '1','portal' => 'Portal1','portal_id' => '1','role' => 'Role1','role_id'  => '1','permission' => 'Permission1','permission_id' => '1'),
    array('group' => 'Group1','group_id' => '1','portal' => 'Portal1','portal_id' => '1','role' => 'Role1','role_id'  => '1','permission' => 'Permission2','permission_id' => '2'),
    array('group' => 'Group1','group_id' => '1','portal' => 'Portal2','portal_id' => '2','role' => 'Role1','role_id'  => '1','permission' => 'Permission3','permission_id' => '3'),
    array('group' => 'Group1','group_id' => '1','portal' => 'Portal2','portal_id' => '2','role' => 'Role2','role_id'  => '2','permission' => 'Permission1','permission_id' => '1'),
    array('group' => 'Group2','group_id' => '2','portal' => 'Portal1','portal_id' => '1','role' => 'Role3','role_id'  => '3','permission' => 'Permission1','permission_id' => '1'),
    array('group' => 'Group2','group_id' => '2','portal' => 'Portal1','portal_id' => '1','role' => 'Role3','role_id'  => '3','permission' => 'Permission2','permission_id' => '2')
);

Псевдо-вывод после:

            (Group_Name = Group1, Group_ID = 1)
(Portal_Name = Portal1, Portal_id = 1) (Portal_Name = Portal2, Portal_id = 2)
(Role,RoleID)                        (Role,RoleID)
(Permission,Permission_id)           (Permission,Permission_id)

Вот функция WIP. Это немного повсюду банкомат, но вот где моя голова:

//List of keyList to compare against
if(is_array($testArray[0])) {
    $keyList = array_keys($testArray[0]);
}


function buildTree(&$data, $keyList) {
    $branch = array();
    $tree = array();

    foreach($keyList as $k => &$keyName) {

        //Each row in the data set is an array
        foreach($data as $rowKey => &$rowArraySet) {
            //If the branch key exists, and matches 
            if(isset($rowArraySet[$keyName]) && isset($keyList[$keyName]) &&
                isset($branch[$keyList[$keyName]][$rowArraySet[$keyName]])) {

                if(isset($data[1+$rowKey]) && 
                    $rowArraySet[$keyName] == $data[1+$rowKey][$keyName]) {
                    $branch[$keyName][$rowArraySet[$keyName]] = array_diff($rowArraySet, $rowArraySet[$keyName]);
                    unset($data[$rowKey]);
                }

            }
            //If the branch does not exist, and matches next array record
            else if(isset($data[1+$rowKey]) && 
                    $rowArraySet[$keyName] == $data[1+$rowKey][$keyName]) {
                $branch[$keyName] = array();  
                $branch[$keyName][$rowArraySet[$keyName]] = array_diff($rowArraySet, array($keyName => $rowArraySet[$keyName]));
                unset($data[$rowKey]);
            }
            //Create new branch key (no match)
            else if(isset($rowArraySet[$keyName])) {
                $branch[$keyName] = array();  
                $branch[$keyName][$rowArraySet[$keyName]] = array_diff($rowArraySet, array($keyName => $rowArraySet[$keyName]));
                unset($data[$rowKey]);
            }
            echo $rowKey;
        }
        //Remove keyName from checking
        unset($keyList[$k]);

        //Compare branch
        //$tree[] = buildTree($branch, &$keyList);

        //echo '<pre>';
        //var_dump($branch);
        //die;
    }

    return $tree;
}

Да, я знаю, что в аду есть место для программистов и недокументированного кода. Я думаю так:

  1. Захватить ключи из первого массива в наборе (это отношение типа родитель-потомок, по крайней мере, порядок проверки)
  2. Используйте ключи для сравнения каждого массива друг с другом в наборе (если существует / установлен и т. Д.)
  3. Соответствующие значения создают новую ветвь и перемещают массив, комбинируя их
  4. Проверьте следующий набор и проверьте, существуют ли ключи в ветке
  5. Рекурсивно сортировать ветку после завершения
  6. Вернуть ветвь к массиву дерева и дереву вывода

Как всегда, приветствуются любые указания. Я чувствую, что близок к тому, чтобы это понять, просто не могу осмыслить это. Спасибо.

Отредактируйте согласно рекомендациям.


person dbergunder    schedule 04.04.2014    source источник
comment
Каким образом вы могли бы урезать это и сделать более лаконичным? В нынешнем виде это очень много для чтения.   -  person Patrick Q    schedule 04.04.2014
comment
Будет полезно, если вы предоставите нам массив в удобной для использования форме, которая позволит нам протестировать. НАПРИМЕР. $testing_array = array("group_name" => "learners", "etc" => "et cetera");   -  person larsAnders    schedule 04.04.2014
comment
Да, я его отредактирую и немного поправлю!   -  person dbergunder    schedule 04.04.2014
comment
Чем больше я работал над этой проблемой в эти выходные, тем больше я думаю, что слишком многого жду от массивов, и что, возможно, мне лучше написать базовый узел / вложенный объект, в котором хранятся мои данные и отношения.   -  person dbergunder    schedule 07.04.2014