JavaScript递归无法跳出:JSON递归搜索更新问题求助
Let's work through this together—your code is close, but there are a few key issues stopping it from working as expected:
What's Going Wrong?
Recursive results aren't updating the parent
status
When you callfindAndUpdate(id, array.children, title)inside themapcallback, you're returning its result, but you never assign that result to the outerstatusvariable. So even if the recursive call finds the matching ID, the parent function'sstatusstaysfalse.You're not actually updating the
title
Your function's goal is to update the title for the matching ID, but that critical step is missing from your code.mapisn't the right tool for this jobmapis designed to transform arrays into new arrays, not for side effects (like updating data) or early termination. You're looping through every item even after finding a match, which is inefficient.
Fixed Code
Here's the corrected version with explanations for each change:
var data = { treeData: [ { title: 'United States of America', children: [{ title: 'Chicago', id:4, editOn:false, children:[{ title: 'New Mexico', id:17, editOn:false }] },{ title: 'New York', id:3, editOn:true }], id:0, editOn:false }, { title: 'United Arab Emirate', children: [{ title: 'Abu Dhabi', id:5, editOn:true }], id:1, editOn:true }, { title: 'United Kingdom', children: [{ title: 'London', id:7, editOn:false },{ title: 'Hampshire', id:6, editOn:true }], id:2, editOn:false }, ] }; function findAndUpdate(id, data, newTitle) { let status = false; // Use for...of instead of map to allow early termination for (const item of data) { console.log(item.id, id, "children" in item, status); if (item.id === id) { console.log("Match Found"); // Update the title for the matching item item.title = newTitle; status = true; // Stop checking further items once we find a match break; } // Only recurse if the item has non-empty children if ("children" in item && item.children.length > 0) { // Assign the recursive result to status status = findAndUpdate(id, item.children, newTitle); // If the recursive call found a match, exit the parent loop if (status) break; } } return status; } var s = findAndUpdate(5, data.treeData, "India"); console.log(s); // Logs true console.log(data.treeData[1].children[0].title); // Logs "India"
Key Changes Explained
- Switched to
for...of: This lets us break out of the loop as soon as we find our match, avoiding unnecessary iterations. - Added title update: The line
item.title = newTitlefulfills your core requirement of updating the title for the matching ID. - Propagated recursive status: When we call the function on an item's children, we assign the return value to
status. If the recursive call finds a match, we immediately break out of the parent loop to stop searching. - Added non-empty children check: A small safeguard to avoid calling the function on empty children arrays (prevents unnecessary recursive calls).
Why Your Original Code Returned false
Even when the recursive call found the matching ID, the outer status variable never got updated. The map callback returns the result, but map just collects those returns into a new array (which you weren't using). The outer status remained false because it was never modified by the recursive call.
内容的提问来源于stack exchange,提问作者MD Danish

