Как сделать дерево?

Есть массив
$data = [
	[ 'id' => 1, 'parent_id' => 0, ],
	[ 'id' => 2, 'parent_id' => 0, ],
	[ 'id' => 3, 'parent_id' => 0, ],
	[ 'id' => 4, 'parent_id' => 1, ],
	[ 'id' => 5, 'parent_id' => 1, ],
	[ 'id' => 6, 'parent_id' => 4, ],
	[ 'id' => 7, 'parent_id' => 2, ],
	[ 'id' => 8, 'parent_id' => 2, ],
	[ 'id' => 9, 'parent_id' => 3, ]
];

Нужно получить:
$result = [
	[
		'id' => 1,
		'parent_id' => 0,
		'children' => [
			[
				'id' => 4,
				'parent_id' => 1,
				'children'  => [
					[
						'id' => 6,
						'parent_id' => 4,
					]
				]
			],
			[
				'id' => 5,
				'parent_id' => 1,
				]
		]
	],

	// ...
];

Как сделать дерево, если изначально не ясно сколько уровней оно будет в себя включать? Есть только id и parent. Больше нет ничего
  • Вопрос задан
  • 580 просмотров
Пригласить эксперта
Ответы на вопрос 5
Exploding
@Exploding
wtf?
Ре-кур-си-я. Закопает семена и взрастит из них заветное дерево невиданной красоты!
Ответ написан
delphinpro
@delphinpro
frontend developer
class AdjacencyList
{
    private static $tmpData;

    public static function renderUnorderedList($rgData, \Closure $callback)
    {

        $html = '<ul>';
        foreach ($rgData as $item) {
            $children = $item['children'];
            $item['children'] = !empty($children);
            $html .= '<li>';
            ob_start();
            $callback($item);
            $html .= ob_get_clean();
            if (!empty($children)) {
                $html .= self::renderUnorderedList($children, $callback);
            }
            $html .= '</li>';
        }
        $html .= '</ul>';
        return $html;
    }

    public static function buildTree($rgData, $start = 0, $idKey = 'id', $idParentKey = 'parent_id')
    {
        self::$tmpData = self::assignKeys($rgData);
        $result = self::buildTreeRecursive($start, $idKey, $idParentKey);
        return $result;
    }

    private static function buildTreeRecursive($start, $idKey, $idParentKey)
    {
        $rgResult = array();

        foreach (self::$tmpData as $item) {
            if ($item[$idParentKey] == $start) {
                $item['children'] = self::buildTreeRecursive($item[$idKey], $idKey, $idParentKey);
                $rgResult[] = $item;
            }
        }

        return empty($rgResult) ? null : $rgResult;
    }

    private static function assignKeys($rgData, $key = 'id')
    {
        $tmp = array();
        foreach ($rgData as $item) {
            $tmp[$item[$key]] = $item;
        }
        return $tmp;
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы