web-dev-qa-db-ja.com

親子JSONデータからすべての子を取得する

親子のJSONデータがあり、選択した親からすべての子(ネストされた子)を取得します。

たとえば、私はJSONデータを持っています:

[{
  "id": 1,
  "parent": 0,
  "name": "Parent"
}, {
  "id": 2,
  "parent": 1,
  "name": "Child 1"
}, {
  "id": 3,
  "parent": 2,
  "name": "Grand Child 1"
}, {
  "id": 4,
  "parent": 2,
  "name": "Grand Child 2"
}, {
  "id": 5,
  "parent": 1,
  "name": "Child 2"
}]

そして、私は関数findAllChildren(1)を持っています。ここで、「1」は「親」であり、関数の結果は次のようになります。

[{
  "id": 2,
  "parent": 1,
  "name": "Child 1"
}, {
  "id": 3,
  "parent": 2,
  "name": "Grand Child 1"
}, {
  "id": 4,
  "parent": 2,
  "name": "Grand Child 2"
}, {
  "id": 5,
  "parent": 1,
  "name": "Child 2"
}]

その他の場合、findAllChildren(2)を呼び出すと、関数の結果は以下のようになります。

[{
  "id": 3,
  "parent": 2,
  "name": "Grand Child 1"
}, {
  "id": 4,
  "parent": 2,
  "name": "Grand Child 2"
}]

その場合を解決する関数を作成する適切な方法は何ですか?ありがとうございました。

8
Hidayat

元のデータを反復処理して、parent_idとして指定されたIDを持つアイテムを探すことができます。見つかった場合は、要素のIDを使用して同じことを再帰的に実行します。

ここで確認してください: https://jsfiddle.net/6ydog1tj/2/

function findAllChildren (id, results, depth) {
    for (d in data) {
        if (data[d].parent == id) {
            data[d].depth = depth
            results.Push(data[d])
            findAllChildren(data[d].id, results, depth + 1)
        }
    }
}

var results = []
findAllChildren(1, results, 0)

$('body').append(results.map(function (element) { return Array(element.depth + 1).join(' -> ') + element.name + '<br>' }))

console.log(results)

印刷する

Child 1
-> Grand Child 1
-> Grand Child 2
Child 2
5
Martin Gottweis

すべてのデータを反復処理し、指定されたすべてのidで検索を開始するためのプロパティを持つオブジェクトのようなツリーを構築することをお勧めします。

次に、オブジェクトがウォークされ、結果に対して子供が反復されます。

function getDescendant(id) {
    var result = [];
    Array.isArray(object[id].children) && object[id].children.forEach(function iter(a) {
        result.Push({ id: a.id, parent: a.parent, name: a.name });
        Array.isArray(a.children) && a.children.forEach(iter);
    });
    return result;
}

var data = [{ id: 1, parent: 0, name: "Parent" }, { id: 2, parent: 1, name: "Child 1" }, { id: 3, parent: 2, name: "Grand Child 1" }, { id: 4, parent: 2, name: "Grand Child 2" }, { id: 5, parent: 1, name: "Child 2" }],
    object = function (data, root) {
        var o = {};
        data.forEach(function (a) {
            a.children = o[a.id] && o[a.id].children;
            o[a.id] = a;
            o[a.parent] = o[a.parent] || {};
            o[a.parent].children = o[a.parent].children || [];
            o[a.parent].children.Push(a);
        });
        return o;
    }(data, 0);

console.log(getDescendant(1));
console.log(getDescendant(2));
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2
Nina Scholz

Array.prototype.filterを使用して、述語条件に一致しない項目を配列から削除できます。

filterは配列をループし、反復ごとに関数を実行します。戻り値がtrueの場合、アイテムは返される配列に含まれます。

フィルターに渡されるparentId関数はcurriedです。スコープで検索している親IDをロックし、フィルターが実行する関数を返します。

const data = [{
  "id": 1,
  "parent": 0,
  "name": "Parent"
}, {
  "id": 2,
  "parent": 1,
  "name": "Child 1"
}, {
  "id": 3,
  "parent": 2,
  "name": "Grand Child 1"
}, {
  "id": 4,
  "parent": 2,
  "name": "Grand Child 2"
}, {
  "id": 5,
  "parent": 1,
  "name": "Child 2"
}]

function parentId(id) {
  return function(item) {
    return item.parent === id
  }
}

console.log(
  data.filter(parentId(2))
)
1
synthet1c