当前位置: 首页 > news >正文

javascript实现一个函数,将数组中的元素随机打乱顺序

大白话javascript实现一个函数,将数组中的元素随机打乱顺序

下面我会详细介绍几种用 JavaScript 实现随机打乱数组元素顺序的方法,同时加上代码注释。

方法一:Fisher-Yates 洗牌算法

这是一种经典的洗牌算法,其核心思想是从数组的最后一个元素开始,依次向前遍历,对于每个位置,随机选择一个前面的位置(包括当前位置)的元素与之交换。

function shuffleArray1(array) {
    // 获取数组的长度
    let len = array.length;
    // 当数组还有多个元素未处理时
    while (len > 0) {
        // 生成一个 0 到 len - 1 之间的随机整数,作为要交换的位置
        let randomIndex = Math.floor(Math.random() * len);
        // 将 len - 1 位置的元素与随机位置的元素交换
        [array[len - 1], array[randomIndex]] = [array[randomIndex], array[len - 1]];
        // 处理下一个元素,数组长度减 1
        len--;
    }
    return array;
}

// 测试数组
let testArray1 = [1, 2, 3, 4, 5];
console.log(shuffleArray1(testArray1));

方法二:使用 sort 方法和随机比较函数

这种方法利用了 JavaScript 数组的 sort 方法,通过传入一个随机的比较函数,让数组元素随机排序。

function shuffleArray2(array) {
    // 使用 sort 方法和随机比较函数
    return array.sort(() => Math.random() - 0.5);
}

// 测试数组
let testArray2 = [1, 2, 3, 4, 5];
console.log(shuffleArray2(testArray2));

实现原理思路总结

  • Fisher-Yates 洗牌算法:它的优点是每个元素在每个位置出现的概率是相等的,是一种公平的洗牌算法。通过不断地随机交换元素,让数组元素的顺序变得随机。
  • 使用 sort 方法和随机比较函数:这种方法比较简单,但由于 sort 方法的实现原理,它并不是一种完全公平的洗牌算法,有些元素可能会有更高的概率出现在某些位置。不过在一些对随机性要求不是特别高的场景下,这种方法也可以使用。

除了Fisher-Yates 洗牌算法,还有哪些方法可以实现数组元素的随机打乱?

除了 Fisher - Yates 洗牌算法外,下面为你介绍另外几种实现数组元素随机打乱的方法,同时会给出代码示例并加上详细注释。

1. 随机选择元素法

这种方法的思路是,不断从原数组中随机选取元素,添加到新数组中,同时从原数组中移除该元素,直到原数组为空。

function shuffleArrayByRandomSelection(arr) {
    // 创建一个空数组用于存储打乱后的元素
    let shuffled = [];
    // 当原数组还有元素时,继续循环
    while (arr.length > 0) {
        // 生成一个 0 到原数组长度减 1 之间的随机索引
        let randomIndex = Math.floor(Math.random() * arr.length);
        // 从原数组中取出该随机索引对应的元素
        let randomElement = arr[randomIndex];
        // 将该元素添加到新数组中
        shuffled.push(randomElement);
        // 从原数组中移除该元素
        arr.splice(randomIndex, 1);
    }
    return shuffled;
}

// 测试数组
let testArray1 = [1, 2, 3, 4, 5];
console.log(shuffleArrayByRandomSelection([...testArray1]));

2. 结合 Math.random() 和 splice() 优化版

此方法与上面的随机选择元素法类似,但在代码实现上更简洁一些。

function shuffleArrayOptimized(arr) {
    let newArr = [];
    // 复制原数组,避免修改原数组
    let tempArr = [...arr];
    while (tempArr.length > 0) {
        // 随机选择一个索引
        let index = Math.floor(Math.random() * tempArr.length);
        // 把该索引对应的元素添加到新数组
        newArr.push(tempArr[index]);
        // 从临时数组中移除该元素
        tempArr.splice(index, 1);
    }
    return newArr;
}

// 测试数组
let testArray2 = [1, 2, 3, 4, 5];
console.log(shuffleArrayOptimized([...testArray2]));

实现原理思路总结

  • 随机选择元素法:通过不断从原数组中随机挑出元素放到新数组里,原数组中的元素就会被逐步打乱到新数组中。因为每次选择都是随机的,所以能实现打乱效果。不过由于频繁使用 splice 方法,当数组很大时,性能可能会受到影响。
  • 结合 Math.random() 和 splice() 优化版:核心思路和随机选择元素法一样,只不过将原数组复制了一份,避免修改原数组,代码结构上更加清晰明了,同样在处理大数组时性能方面会存在一定的问题。

这些方法虽然都能实现数组元素的随机打乱,但在性能和随机性的均匀性上可能会有所差异。在实际使用时,可根据具体的需求来选择合适的方法。

相关文章:

  • 如何用C#继承提升游戏开发效率?Enemy与Boss案例解析
  • 什么是ecovadis认证?ecovadis认证的好处?ecovadis认证的重要意义
  • 案例4:鸢尾花分类(pytorch)
  • 【Docker系列八】使用 Docker run 命令部署 Nginx
  • 初识哈希表
  • 详解接口的常见请求方式
  • 机器学习(八)
  • 1342 摆放小球
  • uniapp中props的用法
  • 3.24学习总结 Java多态+包和final关键字
  • 大文件切片上传和断点续传
  • Typora1.10破解教程
  • 数智读书笔记系列024《主数据驱动的数据治理 —— 原理、技术与实践》
  • SSM整合
  • MySQL MVCC的快照读和当前读区别,Redis的RDB+AOF混合持久化流程。
  • 用SVG绕过浏览器XSS审计
  • Axure项目实战:智慧城市APP(五)新闻资讯、就业信息(动态面板)
  • 微调0.5 B-32B模型要达到85%的准确率需要的数据和资源-会话质检和会话小结
  • 比手动备份快 Iperius全自动加密备份,NAS/云盘/磁带机全兼容
  • MagicFlow-防火墙网关-任意文件读取漏洞
  • 价格周报|本周猪价继续下探,机构预计今年猪价中枢有支撑
  • 信俗与共:清代新疆回疆儒释道庙宇的中华政教
  • 机器人为啥热衷“搞体育”,经济日报:是向加速融入日常生活发起的冲锋
  • 英国6月初将公布对华关系的审计报告,外交部:望英方树立正确政策导向
  • 中国社联成立95周年,《中国社联期刊汇编》等研究丛书出版
  • 南昌上饶领导干部任前公示:2人拟提名为县(市、区)长候选人