在某些情况下,我们从数据库获取项目,我们有这种代码:
const [dataRcdArray, setDataRcdArray] = useState<never[]>([]);
.....
snapshot.forEach((child:IteratedDataSnapshot) => {
setDataRcdArray(arr => [...arr, child] as never[])
});
在上面的代码中,来自实时数据库的项目被找到并存储在名为 dataRcdArray 的数组中。这很好用,除非我们希望最终结果是随机排序的。
为了获得一些随机性,而不总是与上面相同的顺序。
我可以使用这个代码块:
snapshot.forEach((child:IteratedDataSnapshot) => {
const randomVal = Math.floor(Math.random() * 2)
if (randomVal%2) setDataRcdArray(arr => [...arr, child] as never[])
else setDataRcdArray(arr => [child, ...arr] as never[])
});
如果数据库中只有两个项目,此代码将完美运行。但从 3 及以上开始,很容易看出所产生的随机性远非完美。例如,我们可以想象三件物品会发生什么。从数据库读取的最后一项始终位于最终数组的最终位置或起始位置,但绝不会位于中间;表明这不是真正的随机性。
我的问题来了。除了这两个选项:
setDataRcdArray(arr => [...arr, child] as never[])
setDataRcdArray(arr => [child, ...arr] as never[])
有没有一种方法可以在这种情况下工作(知道 dataRcdArray 是一个状态变量),将最后读取的项目插入 dataRcdArray 中的任意位置,而不仅仅是在开头或结尾(这将使我拥有真正的随机性) )?
注意:我所说的真正的随机性,是指在Math.random()可以提供的范围内!
我终于可以通过使用下面的代码达到我想要的结果了:
setDataRcdArray(arr => [...arr, child] as never[])
if (shopCount>=2) {
randomVal = Math.floor(Math.random() * (shopCount))
if (randomVal) {
setDataRcdArray(arr => arr.slice(randomVal).
concat(arr.slice(0,randomVal)) as never[])
}
}