如何停止这个递归函数?
How to stop this recursive function?
我有 javascript 数组,其中每个项目都有对父项的引用,并且它们可以循环(循环引用)。示例:
[
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
]
我需要根据所选记录创建嵌套数据结构以将其显示在 DOM 中,这是我通过如下递归函数实现的(来源 here)
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].parent == parent) {
var children = getNestedChildren(arr, arr[i].id)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
它工作得很好,但不适用于循环数据结构。问题是我需要在它到达它开始的元素之前停止函数执行。
我怎样才能做到这一点?
也许这样的东西对你有用:
function getNestedChildren(arr, parent, visited_list) {
var out = []
for(var i in arr) {
if(!(arr[i].id in visited_list) && (arr[i].parentId == parent)) {
visited_list[arr[i].id] = true;
var children = getNestedChildren(arr, arr[i].id, visited_list)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
nestedList = getNestedChildren(arr, 1, [])
您可以标记您已经访问过的条目。基于此,您可以跳过处理同一元素两次。
当您向元素添加 children
属性 时,您可以将其用于此标记目的,前提是您在元素没有子元素时也创建此 属性。
这是执行此操作的工作代码:
function getNestedChildren(arr, parent) {
var out = [];
for(var i in arr) {
if(arr[i].parentId == parent) {
if (arr[i].children === undefined) {
arr[i].children = []
var children = getNestedChildren(arr, arr[i].id)
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
var arr = [
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
]
getNestedChildren(arr, 1)
// Output the lengths of the children's arrays
document.body.innerHTML = arr.map(function (item) {
return 'Item ' + item.id + ' has ' + item.children.length + ' children.'
}).join('<br>')
checked
数组保留所有 objects (parents) getNestedChildren
的 id
已被调用。
如果当前 child 的 id
在该数组中,请不要将其作为 child。
var arr = [
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
];
var getNestedChildren = function(arr, id, checked) {
var out = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].parentId === id && checked.indexOf(arr[i].id) === -1) {
checked.push(id);
var children = getNestedChildren(arr, arr[i].id, checked);
if (children.length) {
arr[i].children = children;
}
out.push(arr[i]);
}
}
return out;
};
console.log(getNestedChildren(arr, 12, []));
我有 javascript 数组,其中每个项目都有对父项的引用,并且它们可以循环(循环引用)。示例:
[
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
]
我需要根据所选记录创建嵌套数据结构以将其显示在 DOM 中,这是我通过如下递归函数实现的(来源 here)
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].parent == parent) {
var children = getNestedChildren(arr, arr[i].id)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
它工作得很好,但不适用于循环数据结构。问题是我需要在它到达它开始的元素之前停止函数执行。
我怎样才能做到这一点?
也许这样的东西对你有用:
function getNestedChildren(arr, parent, visited_list) {
var out = []
for(var i in arr) {
if(!(arr[i].id in visited_list) && (arr[i].parentId == parent)) {
visited_list[arr[i].id] = true;
var children = getNestedChildren(arr, arr[i].id, visited_list)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
nestedList = getNestedChildren(arr, 1, [])
您可以标记您已经访问过的条目。基于此,您可以跳过处理同一元素两次。
当您向元素添加 children
属性 时,您可以将其用于此标记目的,前提是您在元素没有子元素时也创建此 属性。
这是执行此操作的工作代码:
function getNestedChildren(arr, parent) {
var out = [];
for(var i in arr) {
if(arr[i].parentId == parent) {
if (arr[i].children === undefined) {
arr[i].children = []
var children = getNestedChildren(arr, arr[i].id)
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
var arr = [
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
]
getNestedChildren(arr, 1)
// Output the lengths of the children's arrays
document.body.innerHTML = arr.map(function (item) {
return 'Item ' + item.id + ' has ' + item.children.length + ' children.'
}).join('<br>')
checked
数组保留所有 objects (parents) getNestedChildren
的 id
已被调用。
如果当前 child 的 id
在该数组中,请不要将其作为 child。
var arr = [
{"id": 1, "firstName": "Macko","parentId": 12},
{"id": 2, "firstName": "Jess","parentId": 1},
{"id": 3, "firstName": "Peter","parentId": 1},
{"id": 4, "firstName": "Lisa", "parentId": 1},
{"id": 5, "firstName": "Megan","parentId": 1},
{"id": 6, "firstName": "John", "parentId": 4},
{"id": 7, "firstName": "Joe", "parentId": 4},
{"id": 8, "firstName": "Matthew","parentId": 2},
{"id": 9, "firstName": "Peter","parentId": 2},
{"id": 10, "firstName": "Dio","parentId": 5},
{"id": 11, "firstName": "Hello","parentId": 5},
{"id": 12, "firstName": "Ana", "parentId": 4}
];
var getNestedChildren = function(arr, id, checked) {
var out = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].parentId === id && checked.indexOf(arr[i].id) === -1) {
checked.push(id);
var children = getNestedChildren(arr, arr[i].id, checked);
if (children.length) {
arr[i].children = children;
}
out.push(arr[i]);
}
}
return out;
};
console.log(getNestedChildren(arr, 12, []));