2016-10-11 26 views
6

親子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" 
}] 

およびIは "1" が "親" である機能findAllChildren(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" 
}] 

と私は(2)findAllChildrenを呼び出した場合、他の場合には、関数の結果は以下の好きなはずです。

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

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

+0

希望の結果を追加してください。データは注文されていますか?上のレベルよりもネストされたレベルはありますか?あなたが 'id = 1'を取得したい場合、起こるはずですか? –

+1

はすでに – Hidayat

答えて

3

あなただけのオリジナルデータを反復処理すると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 
+0

こんにちはマーティン、私も巨大な子供を含むデータを取得したい。 – Hidayat

+0

与えられた入力に対して希望の出力で質問を変更できますか?質問では、 'parent = 2'で項目を取り出します。 –

+0

すでに詳しい質問 – Hidayat

2

私はすべてのデータを繰り返し、すべての与えられた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; }

+0

です。こんにちは@ nina-scholz、私は巨大な子供を含むデータを取得したい。例えば、もし私がparent = 1を渡すと、id = 2のデータを取得する必要があります。 – Hidayat

+0

@ nina-scholzありがとうございました。私はマーティンから素晴らしいソリューションを手に入れました。 – Hidayat

1

をあなたは述語条件に一致しない配列から項目を削除するArray.prototype.filterを使用することができます。

filterは、配列をループし、反復ごとに関数を実行します。戻り値がtrueの場合、項目は返された配列に格納されます。

フィルタに渡されるparentIdの機能は、であり、です。スコープ内で検索している親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)) 
 
)

+0

こんにちは@ synthet1c、私もグランド子供を含むデータを取得したい。 – Hidayat

+0

@Hidayatあなたはそれをツリーに構造化したいのですか? – synthet1c

+0

いいえ親ノードから子と大子(ネスト)を検索します。 – Hidayat

関連する問題