51

私はインターネットを見回しましたが、探しているものがまったく見つかりませんでした。「id」と「parent_id」を含む各要素を持つフラットな配列があります。各要素には 1 つの親しかありませんが、複数の子を持つことができます。parent_id = 0 の場合、ルート レベルのアイテムと見なされます。フラット配列をツリーに入れようとしています。私が見つけた他のサンプルは、要素を親にコピーするだけで、オリジナルはまだ存在しています。

編集

開始配列の各要素は、個別の XML ファイルから読み取られます。親がない場合、ファイル自体のparent_idの値は「0」になります。キーは実際には文字列です。

先程は混乱させて申し訳ありませんでした。うまくいけば、これはより明確です:

/編集

私の開始配列:

配列
(
    [_319_] => 配列
        (
            [id] => 0
            [親ID] => 0
        )

    [_320_] => 配列
        (
            [ID] => _320_
            [親ID] => 0
        )

    [_321_] => 配列
        (
            [ID] => _321_
            [parent_id] => _320_
        )

    [_322_] => 配列
        (
            [id] => _322_
            [parent_id] => _321_
        )

    [_323_] => 配列
        (
            [ID] => _323_
            [親ID] => 0
        )

    [_324_] => 配列
        (
            [ID] => _324_
            [parent_id] => _323_
        )

    [_325_] => 配列
        (
            [id] => _325_
            [parent_id] => _320_
        )
)

ツリーが作成された後の結果の配列:

配列
(
    [_319_] => 配列
        (
            [ID] => _319_
            [親ID] => 0
        )

    [_320_] => 配列
        (
            [ID] => _320_
            [親ID] => 0
            [子] => 配列
                (
                    [_321_] => 配列
                        (
                            [ID] => _321_
                            [parent_id] => _320_
                            [子] => 配列
                                (
                                    [_322_] => 配列
                                        (
                                            [id] => _322_
                                            [parent_id] => _321_
                                        )
                                )
                        )
                    [_325_] => 配列
                        (
                            [id] => _325_
                            [parent_id] => _320_
                        )
                )
    [_323_] => 配列
        (
            [ID] => _323_
            [親ID] => 0
            [子] => 配列
                (
                    [_324_] => 配列
                        (
                            [ID] => _324_
                            [parent_id] => _323_
                        )
                )
        )

どんな助け/指導も大歓迎です!

私がこれまでに持っているいくつかのコード:

        function buildTree(array &$elements, $parentId = 0) {
        $branch = 配列();

        foreach ($elements as $element) {
            if ($element['parent_id'] == $parentId) {
                $children = $this->buildTree($elements, $element['id']);
                if ($children) {
                    $element['children'] = $children;
                }
                $branch[] = $element;
            }
        }

        $ブランチを返します。
    }

4

13 に答える 13

68

unset()あなたはそこの兄弟を忘れました。

function buildTree(array &$elements, $parentId = 0) {
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[$element['id']] = $element;
            unset($elements[$element['id']]);
        }
    }
    return $branch;
}
于 2012-01-12T20:36:02.960 に答える
6

これは私のために働きます:

$index=array();
$tree=array();
foreach ($ori as $key=>$var) {
  $var=array_shift($ori);
  if ($var['id']==0) $var['id']=$key;
  if ((string)$var['parent_id']==='0') {
    $tree[$key]=$var;
    $index[$key]=&$tree[$key];
  } else if (isset($index[$var['parent_id']])) {
    if (!isset($index[$var['parent_id']]['children'])) $index[$var['parent_id']]['children']=array();
    $index[$var['parent_id']]['children'][$key]=$var;
    $index[$key]=&$index[$var['parent_id']]['children'][$key];
  } else {
    array_push($ori,$var);
  }
}
unset($index);
print_r($tree);
于 2012-01-12T19:22:04.123 に答える
4

ロジックを確認できます。これを結果に保存します。

Array
(
    [0] => Array
        (
            [id] => 0
            [parent_id] => 0
        )

    [1] => Array
        (
            [id] => 1
            [parent_id] => 0
        )

IMHO、parent_id = o、[1] は [0] の子であってはいけませんか?

とにかく、救助への言及:

$tree = array();
foreach($inputarray as $item){
     if(!isset($tree[$item['id']])) $tree[$item['id']] = array();
     $tree[$item['id']] = array_merge($tree[$item['id']],$item);
     if(!isset($tree[$item['parent_id']])) $tree[$item['parent_id']] = array();
     if(!isset($tree[$item['parent_id']]['children'])) $tree[$item['parent_id']]['children'] = array();
     $tree[$item['parent_id']]['children'][] = &$tree[$item['id']];
}
$result = $tree[0]['children'];
unset($tree);
print_r($result);

root としての「マジック」ナンバーと既存の ID の両方として 0 を悪用したため、id=0 ブランチで再帰が発生しました。if($item['parent_id']!=$item['id'])前に追加するとそれ$tree[$item['parent_id']]['children'][] = &$tree[$item['id']];を防ぐことができますが、きれいではありません。

于 2012-01-12T18:38:04.880 に答える
3

この関数 (parent_id,id,title) を使用して、わずかに異なるソース配列を構築することができます。

$q = mysql_query("SELECT id, parent_id, name FROM categories");
while ($r = mysql_fetch_row($q)) {
  $names[$r[0]] = $r[2];
  $children[$r[0]][] = $r[1];
 }

function render_select($root=0, $level=-1) {
  global $names, $children;
  if ($root != 0)
    echo '<option>' . strrep(' ', $level) . $names[$root] . '</option>';
  foreach ($children[$root] as $child)
    render_select($child, $level+1);
}

echo '<select>';
render_select();
echo '</select>';
  1. より効率的な階層システム
于 2012-01-12T18:40:12.943 に答える
1

これでいくつかの問題が解決するはずなので、MySQL で階層データを保存およびロードする方法を検討したいと考えています。最初の配列は、データベースから直接取得したデータを表していると思いますか?

隣接モデルを使用してデータを階層構造に編成しようとしているようです。ネストを使用してこれを実現する方法は他にもあります。このデータをデータベースから取得していない場合、これはあまり役に立たない可能性があります。

このリンクが役に立ちます: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

于 2012-01-12T18:48:20.283 に答える
0

これは私のソリューションであり、他のソリューションをコピーして最適化します。

function buildTree(array &$elements, $parentId = 0) {
    $branch = array();
    foreach ($elements as $key => $element) {
        if ($element['parent_id'] == $parentId) {
            $children = $this->buildTree($elements, $key);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[$key] = $element;
            unset($elements[$key]);
        }
    }
    return $branch;
}
于 2015-02-27T16:13:03.340 に答える