Quantcast
Viewing all articles
Browse latest Browse all 8892

JavaScriptで木構造をラクに扱う

はじめに

この記事はJavaScriptで木構造をラクに扱う方法について、ロゴスウェア株式会社の社内勉強会で取り上げたものです。

1. 木構造を楽に扱うためのライブラリ

以下の2つがオススメです。

2. tree-model-js

木構造のデータについて、ノードの検索やフィルタ等々の操作をうまいことやってくれるライブラリです。

2-1. 呼び出し方

constTreeModel=require('tree-model');consttree=newTreeModel();

2-2. 期待するデータの形式

tree-model-jsでは、入れ子になっている木構造のオブジェクトを入力にとります。
ここでは以下のような組織図の木構造のデータを例にします。

組織図

Image may be NSFW.
Clik here to view.
org.png

上記組織図を表すオブジェクト

以下のようにchildrenプロパティの配列に子組織のオブジェクトを入れて表現します。

consttreeDataStructure={id:1,name:'全社',children:[{id:11,name:'つくばオフィス'children:[{id:111,name:'システムアンドサービスグループ'}]},{id:12,name:'東京オフィス',children:[{id:121,name:'スイートプロダクトデザイングループ'},{id:122,name:'アクティブ・ラーニングデザイングループ'}]},{id:13,name:'不明のグループ'}]};

2-3. Rootノードオブジェクトを作成する

tree-model-jsparseヘルパーに上記の入れ子のデータを入れて、対象の木構造のRootノードのオブジェクトを作成します。

// 木構造のオブジェクトをパースしてRootノードオブジェクトを作成constroot=tree.parse(treeDataStructure);

2-4. ノードを検索する

idが121のノードを検索してノードを取得する例です。

constnode121=root.first(node=>node.model.id===121);console.log(node121.model);// modelプロパティを使えば、ノードのプロパティを取得できる。// -> { id: 121, name: 'SPD' }

2-5. ノードをフィルターする

idが100以上のノードを全て取得する例です。

constnodesGt100=root.all(node=>node.model.id>100);

2-6. ノードを走査する

ツリーを上から辿って、ノードのidを順番に出力する例です。

root.walk(node=>{console.log(node.model.id)});/*
1
11
111
12
121
122
13
*/

2-7. 探索アルゴリズムを指定する

上記いずれのAPI(first, all, walk)も、オプションを指定すれば探索アルゴリズムを指定できます。

root.walk({strategy:'breadth'/* 幅優先探索 */},node=>{console.log(node.model.id)});/*
1
11
12
13
111
121
122
*/

以下の3種類がサポートされています。

種類オプション
幅優先探索{ strategy: 'breadth' }
深さ優先探索(ルートから){ strategy: 'pre' }
深さ優先探索(末端から) { strategy: 'post' }

3. list-to-tree

フラットなリストから、2-2. 期待するデータの形式で記載した 入れ子になっている木構造のオブジェクトに変換するライブラリです。

constLTT=require('list-to-tree');constnodeList=[{id:1,parent:0},{id:11,parent:1},{id:111,parent:11}];consttreeDataStructure=newLTT(nodes,{key_id:'id',key_parent:'parent',key_child:'children'}).GetTree()[0];console.log(JSON.stringfy(treeDataStructure,null,2));/*
{
  "children": [
    {
      "children": [
        {
          "id": 111,
          "parent": 11
        }
      ],
      "id": 11,
      "parent": 1
    }
  ],
  "id": 1,
  "parent": 0
}
*/

4. tree-model-js と list-to-tree を組み合わせる

2つを組み合わせれば、
1. フラットな木構造のデータから
2. 入れ子になっている木構造のオブジェクトに変換し、
3. tree-model-jsのRootノードオブジェクトを作成できます。

constTreeModel=require('tree-model');constLTT=require('list-to-tree');// 1. フラットな木構造のデータconstnodeList=[{id:1,parent:0},{id:11,parent:1},{id:111,parent:11}];// 2. 入れ子になっている木構造のオブジェクトconsttreeDataStructure=newLTT(nodes,{key_id:'id',key_parent:'parent',key_child:'children'}).GetTree()[0];// 3. tree-model-jsのRootノードオブジェクトを作成constroot=tree.parse(treeDataStructure);

最後に

間違いや改善点等があればご指摘ください。

参考リンク


Viewing all articles
Browse latest Browse all 8892

Trending Articles