php 如何从数据库中建立一个“子-父”树/嵌套数组?

0wi1tuuw  于 2023-02-07  发布在  PHP
关注(0)|答案(3)|浏览(126)
TABLE `people`
+----+------------+-------+
| sn | name       | upper |
+----+------------+-------+
|  1 | Clement    |     0 |
|  2 | Jean       |     1 |
|  3 | Annie      |     1 |
|  4 | Yuan       |     2 |
|  5 | Mei        |     2 |
|  6 | Blue       |     3 |
|  7 | Yang       |     5 |
|  8 | Lorinda    |     0 |
+----+------------+-------+

其结构如下:

Clement
    Jean
        Yuan
        Mei
            Yang
    Annie   
        Blue
Lorinda

upper表示他/她自己的上层人物。
问题是:如何从MySQL中获取嵌套/多维数组?我以为可以使用循环来获取,但我无法自动获取所有的lower。数组可能如下所示:

Array
(
    [1]=>Array
    (
        [self]=>Clement
        [2]=>Array
        (
            [self]=>Jean
            [4]=>Array
            (
                [self]=>Yuan
            )
            [5]=>Array
            (
                [self]=>Mei
                [7]=>Array
                (
                    [self]=>Yang
                )
            )
        )
        [3]=>Array
        (
            [self]=>Annie
            [6]=>Array
            (
                [self]=>Blue
            )
        )
    )
    [8]=>Array
    (
        [self]=>Lorinda
    )
)

既然我们不知道一个人有多少个"上层"的人,解决的办法应该是一个自动化的功能,建立一个完整的数组,而不仅仅是三维或四维的数组。换句话说,这个功能应该从一个上层的人深入到所有下层的人。

3gtaxfhh

3gtaxfhh1#

假设您的输入为:

$input = array(
  array('sn' => 1, 'name' => 'Clement', 'upper' => 0),
  array('sn' => 2, 'name' => 'Jean',    'upper' => 1),
  array('sn' => 3, 'name' => 'Annie',   'upper' => 1),
  array('sn' => 4, 'name' => 'Yuan',    'upper' => 2),
  array('sn' => 5, 'name' => 'Mei',     'upper' => 2),
  array('sn' => 6, 'name' => 'Blue',    'upper' => 3),
  array('sn' => 7, 'name' => 'Yang',    'upper' => 5),
  array('sn' => 8, 'name' => 'Lorinda', 'upper' => 0),
);

使用references,您可以使用以下循环构建树:

$map = array();

foreach ($input as $node) {
  // init self
  if (!array_key_exists($node['sn'], $map)) {
    $map[$node['sn']] = array('self' => $node['name']);
  }
  else {
    $map[$node['sn']]['self'] = $node['name'];
  }

  // init parent
  if (!array_key_exists($node['upper'], $map)) {
    $map[$node['upper']] = array();
  }

  // add to parent
  $map[$node['upper']][$node['sn']] = & $map[$node['sn']];
}

print_r($map[0]);

演示http://3v4l.org/vuVPu

vc6uscn9

vc6uscn92#

假设数据是这样的

$data = array(
    array(1, 'Clement', 0),
    array(2, 'Jean   ', 1),
    array(3, 'Annie  ', 1),
    array(4, 'Yuan   ', 2),
    array(5, 'Mei    ', 2),
    array(6, 'Blue   ', 3),
    array(7, 'Yang   ', 5),
    array(8, 'Lorinda', 0),
);

这个递归函数可以工作:

function tree($data, $node) {
    foreach($data as $e)
        if($e[2] == $node[0])
            $node['children'] []= tree($data, $e);
    return $node;
}

像这样使用它:

$tree = tree($data, array(0));
print_r($tree);
mzillmmw

mzillmmw3#

使用参考Map

$input = array(
  array('sn' => 1, 'name' => 'Clement', 'upper' => 0),
  array('sn' => 2, 'name' => 'Jean',    'upper' => 1),
  array('sn' => 3, 'name' => 'Annie',   'upper' => 1),
  array('sn' => 4, 'name' => 'Yuan',    'upper' => 2),
  array('sn' => 5, 'name' => 'Mei',     'upper' => 2),
  array('sn' => 6, 'name' => 'Blue',    'upper' => 3),
  array('sn' => 7, 'name' => 'Yang',    'upper' => 5),
  array('sn' => 8, 'name' => 'Lorinda', 'upper' => 0),
);

$map = []; // map a reference by id for each item
foreach ($input as &$inp) {
  $map[$inp['sn']] = &$inp;
}

foreach ($map as &$_inp) { // assign each item to its parent, with help of the map
  if ($_inp['upper']) {
    $map[$_inp['upper']]['children'] = &$map[$_inp['upper']]['children'] ?? [];
    $map[$_inp['upper']]['children'][] = &$_inp;
  }
}
$result = array_filter($map, fn($item) => !$item['upper']);

print_r($result);```

相关问题