Javascript 在第一次调用时工作但在第二次调用时不工作的递归函数
尝试在node.js中创建递归函数时,第一个调用有效,但第二个调用失败 为了更容易地向您展示我失败的地方,我举了一个例子,用一个对象数组替换了数据库,并在其中搜索函数findElementsJavascript 在第一次调用时工作但在第二次调用时不工作的递归函数,javascript,node.js,recursion,Javascript,Node.js,Recursion,尝试在node.js中创建递归函数时,第一个调用有效,但第二个调用失败 为了更容易地向您展示我失败的地方,我举了一个例子,用一个对象数组替换了数据库,并在其中搜索函数findElements let data = [ {id: 1, value: "1st", articleId: 1, lvl: 0, sons: [3, 7], positif: 3, negatif: 2}, {id: 2, value: "2nd", articleId: 2, lvl: 0, sons: [],
let data = [
{id: 1, value: "1st", articleId: 1, lvl: 0, sons: [3, 7], positif: 3, negatif: 2},
{id: 2, value: "2nd", articleId: 2, lvl: 0, sons: [], positif: 5, negatif: 8},
{id: 3, value: "3rd", articleId: 1, lvl: 1, sons: [5, 6, 8], positif: 9, negatif: 4},
{id: 4, value: "4th", articleId: 1, lvl: 0, sons: [], positif: 3, negatif: 52},
{id: 5, value: "5th", articleId: 1, lvl: 2, sons: [], positif: 8, negatif: 2},
{id: 6, value: "6th", articleId: 1, lvl: 2, sons: [9], positif: 3, negatif: 1},
{id: 7, value: "7th", articleId: 1, lvl: 1, sons: [], positif: 5, negatif: 0},
{id: 8, value: "8th", articleId: 1, lvl: 2, sons: [], positif: 3, negatif: 0},
{id: 9, value: "9th", articleId: 1, lvl: 3, sons: [], positif: 123, negatif: 102}
]
function findElements(object, elementName, value) {
let res = []
object.forEach((element) => {
if(element[elementName] == value){
res.push(element)
}
})
return res
}
function recursiveFindSons(element) {
for (let i = 0; i < element.length; i++) {
for (let j = 0; j < element[i].sons.length; j++) {
console.log(element[i].sons[j])
element[i].sons[j] = findElements(data, 'id', element[i].sons[j])[0]
if(element[i].sons[j].sons.length>0)
{
element[i].sons[j] = recursiveFindSons([element[i].sons[j]])
}
}
}
return element
}
app.get('/', function(req, res) {
let result = recursiveFindSons(findElements(data, 'lvl', 0))
let json = JSON.stringify({result}, null, 2)
res.status(200).send(json)
})
第二次呼叫的日志:
[ { id: 3,
value: '3rd',
articleId: 1,
lvl: 1,
sons: [ [Object], [Object], [Object] ],
positif: 9,
negatif: 4 } ]
我知道有些东西会将第一次调用的结果保留在内存中,但我不知道如何避免,我也不明白为什么。。。谁能帮我解释一下吗
使用SciFiThief解决方案编辑
function recursiveFindSons(elements, result) {
function copyElement(element) {
return {id: element.id, value: element.value, articleId: element.articleId, lvl: element.lvl, sons: [], positif: element.positif, negatif: element.negatif}
}
if(!result) {
result = []
for(var i=0; i<elements.length; i++) {
result.push(copyElement(elements[i]))
}
}
for (let i = 0; i < elements.length; i++) {
for (let j = 0; j < elements[i].sons.length; j++) {
let elById = findElements(data, 'id', elements[i].sons[j])[0]
result[i].sons.push(copyElement(elById))
console.log(result)
if(elById.sons.length>0)
{
result[i].sons[j] = recursiveFindSons([elById], result[i].sons[j][0])[0]
}
}
}
return result
}
函数递归findsons(元素、结果){
函数copyElement(元素){
返回{id:element.id,value:element.value,articleId:element.articleId,lvl:element.lvl,子项:[],positif:element.positif,negatif:element.negatif}
}
如果(!结果){
结果=[]
对于(var i=0;i0)
{
结果[i].sons[j]=recursiveFindSons([elById],结果[i].sons[j][0])[0]
}
}
}
返回结果
}
您可以使用节点检查器来调试应用程序,彻底检查函数的每一行。你会很快发现它出了什么问题
function recursiveFindSons(element) {
for (let i = 0; i < element.length; i++) {
for (let j = 0; j < element[i].sons.length; j++) {
// 1. The next line is mutating the data you go through
element[i].sons[j] = findElements(data, 'id', element[i].sons[j])[0]
if(element[i].sons[j].sons.length > 0) {
element[i].sons[j] = recursiveFindSons([element[i].sons[j]]);
}
}
}
return element;
}
它将替换数据数组中对象项的“子”数组中的id。
这里也一样:
element[i].sons[j] = recursiveFindSons([element[i].sons[j]]);
我假设您需要提供的第一个日志的输出。要做到这一点,您可以这样做:
function recursiveFindSons(elements, result) {
result = result || []; // define result array on first call or use it from args.
// There's no original data mutations, only local result variable
for (let i = 0; i < elements.length; i++) {
for (let j = 0; j < elements[i].sons.length; j++) {
let son = elements[i].sons[j];
result.push(son);
let elById = findElements(data, 'id', son)[0];
if(elById.sons.length > 0) {
recursiveFindSons([elById], result); // pass result array to the next function call
}
}
}
return result;
}
函数递归findsons(元素、结果){
result=result | |[];//在第一次调用时定义结果数组或从args使用它。
//没有原始数据突变,只有局部结果变量
for(设i=0;i0){
recursiveFindSons([elById],result);//将结果数组传递给下一个函数调用
}
}
}
返回结果;
}
JSFiddle:谢谢!我不想要我提供的第一个日志,而是在相应的子编号中添加第一个日志的id。对不起,解释得不好。我已经成功地使用了你的解决方案:在原始帖子中编辑代码,让我安排推送到更好的形式,我认为这会很好。
element[i].sons[j] = recursiveFindSons([element[i].sons[j]]);
function recursiveFindSons(elements, result) {
result = result || []; // define result array on first call or use it from args.
// There's no original data mutations, only local result variable
for (let i = 0; i < elements.length; i++) {
for (let j = 0; j < elements[i].sons.length; j++) {
let son = elements[i].sons[j];
result.push(son);
let elById = findElements(data, 'id', son)[0];
if(elById.sons.length > 0) {
recursiveFindSons([elById], result); // pass result array to the next function call
}
}
}
return result;
}