You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中两次调用shuffle函数返回相同结果的问题求助

问题分析与解决方案

你的问题根源在于**shuffle函数原地修改数组并返回原引用**,导致两次调用实际上操作的是同一个数组对象,最终cards1和cards2指向的是同一个结果。

具体原因

看你的shuffle函数:

export const shuffle=(a)=> {
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

它直接修改了传入的数组a,然后返回同一个数组的引用。当你执行:

const cards1=shuffle(cards)
const cards2=shuffle(cards)

第一次调用已经把cards数组打乱,第二次调用是在这个已经打乱的数组上再次打乱,而且cards1和cards2都是指向cards这个同一个数组,所以最终两者的结果完全一致。

两种解决方案

方案1:修改shuffle函数,操作数组副本

让shuffle函数先创建原数组的浅拷贝,再对副本进行打乱,这样每次调用都会返回一个全新的数组,不会影响原数组和其他调用结果:

export const shuffle=(a)=> {
  // 创建原数组的浅拷贝,避免修改原数组
  const arr = [...a];
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
}

方案2:调用shuffle时传入数组副本

如果你不想修改shuffle函数,可以在每次调用时传入原数组的副本,保证两次打乱操作的是独立的数组:

shuffleCards=()=>{
  const cards=this.props.selectedCards
  // 每次调用shuffle都传入新的数组副本
  const cards1=shuffle([...cards])
  const cards2=shuffle([...cards])
  this.setState({cards1, cards2})
  const id1=cards1.map(c=>c.id)
  const id2=cards2.map(c=>c.id)
  console.log(id1, id2)
}

补充说明

如果你的selectedCards中的元素是复杂对象,[...cards]这种浅拷贝已经足够满足打乱顺序的需求(因为你只是调整元素的位置,不会修改对象内部的属性)。如果需要深拷贝对象,可以使用JSON.parse(JSON.stringify(a))或者第三方库,但在这个场景下浅拷贝完全够用。

内容的提问来源于stack exchange,提问作者Nhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:07:55