写个方法随机打乱一个数组

function shuffleArray(array) {
  // 创建数组的副本,避免修改原始数组
  const shuffledArray = [...array];
  
  // Fisher-Yates 洗牌算法
  for (let i = shuffledArray.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1)); // 随机索引 0 到 i
    [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]]; // 交换元素
  }

  return shuffledArray;
}


// 示例用法:
const originalArray = [1, 2, 3, 4, 5];
const shuffled = shuffleArray(originalArray);
console.log("Original array:", originalArray); // 输出原始数组,保持不变
console.log("Shuffled array:", shuffled); // 输出打乱后的数组


//  简化版 (如果可以直接修改原数组)
function shuffleArrayInPlace(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

// 示例用法
const myArray = [1, 2, 3, 4, 5];
shuffleArrayInPlace(myArray);
console.log("Shuffled array in place:", myArray);


// 使用sort方法的变种 (不推荐 - 分布不均匀)
//  虽然简洁,但由于sort的实现机制,这种方法的随机性不够理想,可能导致某些排列出现的概率更高。
function shuffleArraySort(array) {
  return array.sort(() => Math.random() - 0.5);
}

解释:

  • shuffleArray(array): 这个版本创建了原数组的副本,并在副本上进行洗牌,保持原始数组不变。 这是推荐的做法,因为它避免了副作用。

  • shuffleArrayInPlace(array): 这个版本直接修改传入的数组。 如果你确定要修改原始数组,可以使用这个版本,它更节省内存。

  • shuffleArraySort(array): 这个版本使用 sort 方法和一个随机比较函数。 虽然代码简洁,但它不推荐,因为 sort 方法的随机比较函数会导致分布不均匀,某些排列出现的概率会更高,从而降低随机性。

  • Fisher-Yates 洗牌算法: shuffleArrayshuffleArrayInPlace 使用了 Fisher-Yates 洗牌算法 (也称为 Knuth 洗牌算法)。 这是公认的生成均匀随机排列的有效算法。 它的核心思想是从数组的最后一个元素开始,随机选择一个之前的元素与其交换位置。 然后,对倒数第二个元素重复此过程,依此类推,直到处理完第二个元素。

选择哪个版本取决于你的具体需求。 如果你需要保持原始数组不变,使用 shuffleArray。 如果你可以修改原始数组并且想要节省内存,使用 shuffleArrayInPlace避免使用 shuffleArraySort ,因为它不能保证真正的随机性。

posted @ 2024-11-24 17:35  王铁柱6  阅读(34)  评论(0)    收藏  举报