我正在做一个排序算法可视化项目,我正在实现一个随机播放按钮。可视化涉及不同高度的条形图四处移动。我希望随机播放按钮一次一步地修改条形数组,高速展示每个交换。我已经尝试调整许多不同的东西(其中一些确实以一种奇怪的方式移动条形图),但我似乎无法获得所需的功能。这是一些相关代码:
// Swap does not modify the original array, but the implementation details don't really affect the result.
// It basically swaps two elements in the bar array, and then returns the updated array.
const swapBars = (bars, bar1, bar2) => {
if (!bars || !bar1 || !bar2) {
return;
}
const _bars = bars;
let _bar1 = bar1;
let _bar2 = bar2;
const tempLeft = _bar1.left;
_bar1.left = _bar2.left;
_bar2.left = tempLeft;
const temp = _bar1;
_bar1 = _bar2;
_bar2 = temp;
return _bars;
};
// Init bars is basically synchronous shuffle. It takes the array that is created and shuffles it
// because the array should begin in a shuffled state. This is working properly.
const initBars = (bars) => {
let currentIndex = bars.length - 1;
while (currentIndex > 0) {
// randomIndex will always be different from currentIndex, so each bar will always shuffle
const randomIndex = Math.floor(Math.random() * currentIndex);
swapBars(bars, bars[currentIndex], bars[randomIndex]);
currentIndex--;
}
setBarsToRender(bars);
};
// createBarArray is what is used to actually populate an empty array with bars depending on a number passed
// through by a slider. This is also working properly.
const createBarArray = (quantity) => {
let bars = [];
const width = calcWidthPercentage(quantity);
for (let i = 0; i < quantity; i++) {
const height = calcHeightPercentage(quantity, i + 1);
const left = calcLeftPosPercentage(quantity, i + 1);
bars.push({ correctPos: i, height: height, width: width, left: left });
}
return initBars(bars);
};
// shuffleBars seems to be broken. I've tried many different things, and this is just the latest snapshot of it.
// It is being called when the shuffle button is being clicked using `shuffleBars(barsToRender)` where barsToRender is the stateful value that is being rendered.
const shuffleBars = (bars) => {
let currentIndex = bars.length - 1;
while (currentIndex > 0) {
const randomIndex = Math.floor(Math.random() * currentIndex);
setTimeout(() => {
setBarsToRender((prev) => {
return swapBars(prev, prev[currentIndex], prev[randomIndex]);
});
}, 50 * (bars.length - currentIndex));
currentIndex--;
}
};
如果我做一些事情,比如将 swapBars
调用移到 setBarsToRender
里面,然后
做 setBarsToRender[...bars]
,我可以看到一些条形图在移动,但不是预期的行为(最小的条形图是唯一不断交换的条形图)。我不确定我是否误解了状态更新在 setTimeout 中的工作方式,或者它是否是其他东西,所以我非常感谢一些帮助。