ホームページ > ウェブフロントエンド > jsチュートリアル > 無限再帰ツリーを実装する JavaScript コードの例

無限再帰ツリーを実装する JavaScript コードの例

不言
リリース: 2019-03-29 09:37:37
転載
2633 人が閲覧しました

この記事の内容は、JavaScript で無限再帰ツリーを実装するためのコード例に関するものですが、一定の参考価値がありますので、困っている方は参考にしていただければ幸いです。

需要: 最近、要件に遭遇しました。通常、ツリー構造をフロントエンドに直接返すためにバックエンドによって使用されていました。フロントエンドは、この入れ子になったタイプのデータ (カスケードなど) に非常に敏感です。領域またはメニューのツリー構造)。) は処理の層を節約します。バックグラウンド展開を変更した後、フラット化された配列データがフロントエンドに返され、次のデータが処理されます。急にちょっとパニックになった…

const data = [
    {
        "area_id": 5,
        "name": "广东省",
        "parent_id": 0,
    },  
    {
        "area_id": 6,
        "name": "广州市",
        "parent_id": 5,
    },
    {
        "area_id": 7,
        "name": "深圳市",
        "parent_id": 5,
    },
    {
        "area_id": 4,
        "name": "北京市",
        "parent_id": 3,
    },
    {
        "area_id": 3,
        "name": "北京",
        "parent_id": 0,
    },
    {
        "area_id": 2,
        "name": "测试子地区",
        "parent_id": 1,
    },
    {
        "area_id": 1,
        "name": "测试地区",
        "parent_id": 0,
    }
]
ログイン後にコピー

えっと、気持ちを切り替えて、運動して腕まくりしてやるのがちょうどいい、と考えて、以下の2つを整理しました。メソッド~

方法 1 - 再帰

##再帰に非常に適したこのようなシナリオでは、どのようにして再帰の役割を省略できるでしょうか?最初の方法は再帰です。再帰の宝を提示します~

function toTreeData(data,pid){
 
    function tree(id) {
        let arr = []
        data.filter(item => {
            return item.parent_id === id;
        }).forEach(item => {
            arr.push({
                area_id: item.area_id,
                label: item.name,
                children: tree(item.area_id)
            })
        })
        return arr
    }
    return tree(pid)  // 第一级节点的父id,是null或者0,视情况传入
}
ログイン後にコピー
まあ、適切にポーズをとって、コンソールで実行してください

無限再帰ツリーを実装する JavaScript コードの例

ああ、悪くないです~背景の弟はいいえもう心配する必要はありません どのデータを返す必要がありますか?ただし、この方法には欠点があり、コンポーネントを使用する際に必要なデータ構造では、子にデータが存在しない場合、[]が返されてしまいます。さて、問題はありますが、最適化は可能です。そう簡単に最適化されたコードを提供できるでしょうか?あなたはすでに成熟したプログラマーなので、自分でコードを最適化する方法を学ぶ必要があります。 ! !

方法2 - オブジェクト

私の目にはオブジェクトは常に天久龍殺しの剣の存在であり、その秘密を理解することは武術の秘伝書を身近に持つようなものである。自分。もちろん、適切に使用しないと金属くずの山と同じであり、予期せぬ結果を招く可能性もあります。

function setTreeData(arr) {
    //  删除所有 children,以防止多次调用
    arr.forEach(function (item) {
            delete item.children;
    });
    let map = {}; // 构建map
    arr.forEach(i => {
        map[i.area_id] = i; // 构建以area_id为键 当前数据为值
    });

    let treeData = [];
    arr.forEach(child => {
        const mapItem = map[child.parent_id]; // 判断当前数据的parent_id是否存在map中

        if (mapItem) { // 存在则表示当前数据不是最顶层数据
        
            // 注意: 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变,踩坑点
            (mapItem.children || ( mapItem.children = [] )).push(child); // 这里判断mapItem中是否存在children, 存在则插入当前数据, 不存在则赋值children为[]然后再插入当前数据
        } else { // 不存在则是组顶层数据
            treeData.push(child);
        }
    });

    return treeData;
};

console.log(setTreeData(data)); // 输出整理后的数据
ログイン後にコピー
結果として、再帰的な結果と同様に、実行されません。私は再帰よりもこのアプローチの方が好きです。しかし、この方法は元のデータを変えてしまうという間違いが起こりやすく、私はずっとここで行き詰まっていたので、子を削除して初期化しました。覚えていますか?覚えていない場合は、3 回繰り返してください。 ! !

概要

上記では、フラット データを再帰ツリーに変換する 2 つの方法を簡単に紹介しました。学習しましたか?まだ学習していない場合は、戻ってコーディングしてください。現在、データをツリー構造に整理する必要に遭遇した場合、それは主にメニューバーや分類のツリー構造であり、もちろん、州や市などの下位構造もあります。

この記事はここで終了しています。その他のエキサイティングなコンテンツについては、PHP 中国語 Web サイトの

JavaScript チュートリアル ビデオ 列に注目してください。 ! !

以上が無限再帰ツリーを実装する JavaScript コードの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート