以随机顺序从实时数据库获取项目

问题描述 投票:0回答:1

在某些情况下,我们从数据库获取项目,我们有这种代码:

  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()可以提供的范围内!

javascript next.js firebase-realtime-database
1个回答
0
投票

我终于可以通过使用下面的代码达到我想要的结果了:

  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[])
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.