固定首尾元素,随机打乱数组中间元素的实现方法
实现固定首尾元素的数组随机打乱函数
嘿,刚好有几个简洁优雅的方案能满足你的需求!核心思路就是单独处理中间需要打乱的元素,再和固定的首尾拼接回去,下面给你两种常用的实现方式:
方案一:Fisher-Yates洗牌算法(推荐,无偏随机)
Fisher-Yates是业界公认的高效且公平的洗牌算法,时间复杂度O(n),能保证每个元素的排列概率均等。我们只需要把中间的子数组抽出来用这个算法打乱,再拼回首尾元素即可:
function customShuffle(arr) { // 边界处理:数组长度小于3时,没有中间元素需要打乱,直接返回副本 if (arr.length <= 2) return [...arr]; // 提取中间需要打乱的部分(从索引1到倒数第二个元素) const middle = arr.slice(1, -1); // Fisher-Yates 原地洗牌 for (let i = middle.length - 1; i > 0; i--) { // 生成0到i之间的随机索引 const randomIndex = Math.floor(Math.random() * (i + 1)); // 交换当前元素和随机索引的元素 [middle[i], middle[randomIndex]] = [middle[randomIndex], middle[i]]; } // 拼接固定首尾和打乱后的中间元素,返回新数组 return [arr[0], ...middle, arr[arr.length - 1]]; } // 测试示例 const x = ['A','B','C','D','E']; console.log(customShuffle(x)); // 输出示例:['A', 'C', 'D', 'B', 'E']
这个方案的优势在于随机性完全公平,而且不会修改原数组(返回新数组,避免副作用),适合对随机性要求较高的场景。
方案二:利用sort快速实现(简洁但随机性稍弱)
如果你的场景对随机性的均匀性要求没那么高,也可以用更简洁的写法,利用数组的sort方法快速打乱中间元素:
function customShuffle(arr) { if (arr.length <= 2) return [...arr]; // 提取中间元素并打乱,这里用Math.random()-0.5实现随机排序 const shuffledMiddle = arr.slice(1, -1).sort(() => Math.random() - 0.5); // 拼接返回 return [arr[0], ...shuffledMiddle, arr[arr.length - 1]]; }
⚠️ 注意:这种方式的随机性不是完全均匀的,因为不同浏览器的sort实现可能会影响结果的分布,所以更适合快速开发、对随机性要求不高的场景。
不管用哪种方案,都能保证你的首元素"A"和尾元素"E"始终在固定位置,中间元素随机打乱~
内容的提问来源于stack exchange,提问作者amaatouq
相关产品推荐
相关产品推荐

