私は次のようなオブジェクトを持つオブジェクトのJavaScript配列を持っています:
itemId
name
parentItemId <== 親のないトップ レベルのアイテムは null 値を持つ
親項目に子の配列が含まれ、該当する場合はそれらの子に子の配列があるグラフを作成したいと考えています。
これについての良い方法は何ですか?
私は次のようなオブジェクトを持つオブジェクトのJavaScript配列を持っています:
itemId
name
parentItemId <== 親のないトップ レベルのアイテムは null 値を持つ
親項目に子の配列が含まれ、該当する場合はそれらの子に子の配列があるグラフを作成したいと考えています。
これについての良い方法は何ですか?
function objectGraph(items)
{
var items_by_id = {};
var roots = [];
var i;
// Build an id->object mapping, so we don't have to go hunting for parents
for (i = 0; i < items.length; ++i) {
items_by_id[items[i].itemId] = items[i];
items[i].children = [];
}
for (i = 0; i < items.length; ++i) {
var parentId = items[i].parentItemId;
// If parentId is null, this is a root; otherwise, it's parentId's kid
var nodes = (parentId === null) ? roots : items_by_id[parentId].children;
nodes.push(items[i]);
}
return roots;
}
このコードはすべてのノードにchildren
プロパティを与えることに注意してください。ノードに子供がいない場合は空です。個人的には、各ノードに子がないかどうかにかかわらず、よりシンプルで一貫性があると思います。children
存在するかどうかを気にせずにループできます。葉ノードにはchildren.length == 0
.
ルートが 1 つだけであることを保証できる場合はreturn roots[0];
、配列を返す代わりにそれを行うことができます。
これは少し大雑把ですが、私があなたの質問を正しく集めていれば、それは仕事をするはずです。子が正しく整理されたトップレベルのオブジェクトの配列を返す必要があります。
注意として、これは単一レベルだけでなく、Nレベルの子オブジェクトに対して機能します。
var finalArray = [];
var YOUR_RAW_ARRAY = [];
var buildObjectGraph = function(inputArray){
var i = 0, len = inputArray.length;
var returnVal = [];
for(;i<len;i++){
if(inputArray[i].parentItemId === null){
findChildren(inputArray[i], inputArray);
returnVal.push(inputArray[i]);
}
}
var findChildren = function(root){
var i = 0, i2 = 0, len = rawDataArray.length, len2 = 0;
for(;i<len;i++){
if(inputArray[i].parentItemId === root.itemId){
if(root.children){
root.children.push(inputArray[i]);
}else{
root.children = [];
root.children.push(inputArray[i]);
}
}
}
//now call it recursively
len2 = root.children.length;
if(len2 > 0){
for(;i2 < len2; i2++){
findChildren(root.children[i2]);
}
}
};
return returnVal;
};
//Then execute it
finalArray = buildObjectGraph(YOUR_RAW_ARRAY);
「ツリービルダー関数」を作成するときは、「最上位のもの」が単一のアイテムなのか、アイテムの配列なのかを判断する必要があります。itemSと言ったので、配列を使用します。違いは、渡して返されるパラメータです。配列の場合はparentIdを渡し、そうでない場合はidを渡します。
function buildTree(parentId, list) {
var nodes = [];
for (var i=0, l; l = list[i]; i++) {
if (l.parentId === parentId) {
// if you need "myList" intact afterwards remove the next line at the cost of efficiency
list.splice(i, 1); i--;
nodes.push({
id: l.id
,parentId: l.parentId
,name: l.name
,children: buildTree(l.id, list)
});
}
}
return nodes;
}
var myTree = buildTree(null, myList);