英文:
Stop propagation of recursive function conditionally
问题
代码:
const [stopVisiting, setStopVisiting] = useState(false);
const startVisiting = (visElement) => {
if (visElement.i === endElement.i && visElement.j === endElement.j) {
setStopVisiting(true);
}
if (visElement.wall === true) return;
if (stopVisiting === true) {
console.log("停止函数");
return;
} else {
if (visElement["visited"] === false) {
var newGrid = [...grid];
newGrid[visElement.i][visElement.j]["visited"] = true;
setGrid(newGrid);
visElement["visited"] = true;
setTimeout(() => {
if (visElement["i"] > 0) {
startVisiting(grid[visElement.i - 1][visElement.j]);
}
if (visElement["i"] < 39) {
startVisiting(grid[visElement.i + 1][visElement.j]);
}
if (visElement["j"] > 0) {
startVisiting(grid[visElement.i][visElement.j - 1]);
}
if (visElement["j"] < 59) {
startVisiting(grid[visElement.i][visElement.j + 1]);
}
return;
}, 500);
}
}
};
它实际上会记录语句 "停止函数",但它不起作用。
wall 元素是被阻挡的空间,我们无法通过它。
英文:
I am creating a pathfinding application, where I have created a grid of size 30*60, there is a starting element from where we have to start the path searching and a ending element where we have to stop the function once we reach the ending, in between I have marked all grids as visited. Also have created a variable named stopVisiting, so that once we reach the destination we will set stopVisiting to true to stop the function. But it is not working,
Code:
const [stopVisiting, setStopVisiting] = useState(false);
const startVisiting = (visElement) => {
if (visElement.i === endElement.i && visElement.j === endElement.j) {
setStopVisiting(true);
}
if (visElement.wall === true) return;
if (stopVisiting === true) {
console.log("Stop the function here");
return;
} else {
if (visElement["visited"] === false) {
var newGrid = [...grid];
newGrid[visElement.i][visElement.j]["visited"] = true;
setGrid(newGrid);
visElement["visited"] = true;
setTimeout(() => {
if (visElement["i"] > 0) {
startVisiting(grid[visElement.i - 1][visElement.j]);
}
if (visElement["i"] < 39) {
startVisiting(grid[visElement.i + 1][visElement.j]);
}
if (visElement["j"] > 0) {
startVisiting(grid[visElement.i][visElement.j - 1]);
}
if (visElement["j"] < 59) {
startVisiting(grid[visElement.i][visElement.j + 1]);
}
return;
}, 500);
}
}
};
It is actually logging the statement Stop the function here, but it not working.
wall element is the blocked space, through which we cannot pass.
答案1
得分: 1
即使您调用了 setStopVisiting(true),您的 stopVisiting 没有被赋予新值,所以 stopVisiting === true 永远不会成立。
相反,不要使用 stopVisiting 状态... 这是不必要的。您可以通过确保将其标记为已访问,然后检查 endElement.visited 来知道是否已经到达了终点,这实际上就是您打算使用 stopVisiting 实现的功能的等效方式。
其他一些注意事项
-
没有必要同时执行以下两个操作,因为它们实现了相同的功能:
newGrid[visElement.i][visElement.j]["visited"] = true; visElement["visited"] = true;这两个赋值操作都会将值赋给同一个对象(请注意,
newGrid是grid的浅拷贝,所以它的对象不是副本,但这没关系)。 -
["visited"]和.visited符号实现了相同的功能。我建议使用后者。 -
您有多个条件可以停止访问元素:
- 达到目标元素
- 撞到墙
- 遇到已经访问过的元素。
这三种情况可以在同一个
if语句中检查。
以下是更新后的代码:
const startVisiting = (visElement) => {
if (visElement.wall || visElement.visited || endElement.visited) return;
visElement.visited = true; // 这将最终设置 `endElement.visited`
setGrid([...grid]);
setTimeout(() => {
const { i, j } = visElement; // 解构以使下面的代码更可读
if (i > 0) startVisiting(grid[i - 1][j]);
if (i < 39) startVisiting(grid[i + 1][j]);
if (j > 0) startVisiting(grid[i][j - 1]);
if (j < 59) startVisiting(grid[i][j + 1]);
}, 500);
};
英文:
Even though you call setStopVisiting(true), your stopVisiting is not getting assigned a new value so stopVisiting === true is never going to be true.
Instead, don't use a stopVisiting state... it is not needed. You can know whether you have reached the end by making sure you mark it as visited and then by checking endElement.visited, which really is the equivalent of what you intended with stopVisiting.
Some other remarks
-
It is not needed to do both of the following, since they achieve the same:
newGrid[visElement.i][visElement.j]["visited"] = true; visElement["visited"] = true;These two assignments assign to the
visitedproperty of the same object (Note thatnewGridis a shallow copy ofgrid, so its objects are not copies, but that's OK). -
The notations
["visited"]and.visitedachieve the same. I'd stick with the latter. -
You have several conditions that stop the process from visiting an element:
- Having reached the target element
- Hitting a wall
- Encountering an element that was already visited.
These three cases can be checked in one and the same
ifstatement
Here is the updated code:
const startVisiting = (visElement) => {
if (visElement.wall || visElement.visited || endElement.visited) return;
visElement.visited = true; // This will eventually set `endElement.visited`
setGrid([...grid]);
setTimeout(() => {
const {i, j} = visElement; // Destructure to make code below more readable
if (i > 0) startVisiting(grid[i - 1][j]);
if (i < 39) startVisiting(grid[i + 1][j]);
if (j > 0) startVisiting(grid[i][j - 1]);
if (j < 59) startVisiting(grid[i][j + 1]);
}, 500);
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论