英文:
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
visited
property of the same object (Note thatnewGrid
is a shallow copy ofgrid
, so its objects are not copies, but that's OK). -
The notations
["visited"]
and.visited
achieve 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
if
statement
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);
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论