[js] 第24天 如何快速让一个数组乱序,写出来
haizhilin2013 opened this issue · 33 comments
第24天 如何快速让一个数组乱序,写出来
直接使用原生的sort()
方法:
var arr= [1,2,3,4,5]
arr.sort(function(a,b){return Math.random() > 0.5 ? 1 : -1})
console.log(arr);// [ 1, 3, 5, 2, 4 ]
使用array.sort()进行乱序存在一定问题,增大样本进行实验之后可以发现这种乱序方案并不是完全随机的(所有元素会大概率停留在自己的初始位置)(v8处理排序是小于10个是插入排序,大于10个是快排,排序算法复杂度介于O(n)与O(n2)之间,也就是存在两个元素都没有比较的机会,因此不是完全随机),这里可以使用Fisher–Yates shuffle(洗牌算法)
Array.prototype.shuffle = function() { var input = this; for (var i = input.length-1; i >=0; i--) { var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex; } return input; } var tempArray = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] tempArray.shuffle(); console.log(tempArray);
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const map = new Map();
arr = arr.map(v => {
const random = Math.random();
map.set(random, v);
return random
}) //arr 替换成随机数, 原数组成员存入map
.sort((a, b) => a - b) //排序随机数
.map(v => map.get(v)); //取出数组成员填入数组
console.log(arr);
arr.sort(function(a,b){ return Math.random()>.5 ? -1 : 1;});
let arr= [1,2,3,4,5,6,7,8,9,10]; arr.map((item,index)=>{ let random =Math.floor(Math.random() * arr.length); [arr[index],arr[random]] = [arr[random],arr[index]]; }); console.log(arr);
为什么楼上要用三元运算符,直接这样不就完事了。。
arr.sort((a, b) => Math.random() - .5)
不过我们team随机算法也用的洗牌算法,思路就是从后往前遍历,然后随机(0, i+1),交换
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1))
[array[i], array[j]] = [array[j], array[i]]
}
}
function mixi(arr){
arr.sort(function(a,b){
(Math,random()>0.5)?a-b>0:a-b<0
})
}
const swap = (arr, index1, index2) => {
;[arr[index1], arr[index2]] = [arr[index2], arr[index1]]
}
export default function shuffle(arr = []) {
if (!Array.isArray(arr)) return
let index = arr.length - 1
for (; index > 0; index++) {
const randomIndex = Math.floor(Math.random() * (index + 1))
swap(arr, index, randomIndex)
}
}
const shuffle = arr => arr.sort(() => Math.random() - 0.5);
//洗牌数组
export function shuffle(arr) {
const _arr = arr.slice();
for (let i = 0; i < _arr.length; i++) {
//调用
let j = getRandomNumber(0, i);
let t = _arr[i];
_arr[i] = _arr[j];
_arr[j] = t;
}
return _arr;
}
//随机取0-1中间值(包括0和1)
export function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1));
}
使用array.sort()进行乱序存在一定问题,增大样本进行实验之后可以发现这种乱序方案并不是完全随机的(所有元素会大概率停留在自己的初始位置)(v8处理排序是小于10个是插入排序,大于10个是快排,排序算法复杂度介于O(n)与O(n2)之间,也就是存在两个元素都没有比较的机会,因此不是完全随机),这里可以使用Fisher–Yates shuffle(洗牌算法)
Array.prototype.shuffle = function() { var input = this; for (var i = input.length-1; i >=0; i--) { var randomIndex = Math.floor(Math.random()*(i+1)); var itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex; } return input; } var tempArray = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] tempArray.shuffle(); console.log(tempArray);
大神,想问下,arr.sort(function(a,b){return Math.random() > 0.5 ? 1 : -1}),这种呢随机不是和Math.random的值密切相关吗,和sort有关系么?我的理解是sort是按照Math.random来排序,Math.random是完全随机的吧,那么这个整体应该也是完全随机的吧
var arr= [1,2,3,4,5]
arr.sort(function(a,b){
return Math.random() > 0.5 ? 1 : -1 // 判断随机数
})
console.log(arr);
const shuffle = ([...arr]) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
};
const foo = [1, 2, 3];
console.log(shuffle(foo))
function messArr(arr) {
let newIndex = [];
let newArr = [];
while (newIndex.length < arr.length) {
let num = Math.floor(Math.random() * arr.length);
if (!newIndex.includes(num)) {
newIndex.push(num);
}
}
for (let index in newIndex) {
newArr.push(arr[newIndex[index]]);
}
return newArr
}
var arr = ['广西', '上海', '北京', '云南'];
console.log(messArr(arr));
function shuffle(array) {
let _array = array.map(v => v)
return array.reduce((acc, cur, curIndex, arr) => {
// 取 [0, 数组长度 - 1] 的随机数
const randomVal = Math.floor(Math.random() * _array.length)
acc.push(
_array[randomVal]
)
// 删除对应的数
_array.splice(randomVal, 1)
return acc
}, [])
}
console.log(randomArray([0,1,2,3,4,5]))
/**
* @param {number[]} arr
* @return {number[]}
*/
function shuffle(arr) {
arr.sort(() => Math.random() - 0.5);
}
shuffle的**·
const randomSort = (arr=[]) => {
const length = arr.length;
for(let index = 0; index < length; index++) {
let randomIndex = Math.floor(Math.random()*(length - index)) + index;
[arr[index], arr[randomIndex]] = [arr[randomIndex], arr[index]]
}
return arr;
}
Array.prototype.shuffle = function () {
let _this = this
for(let i = _this.length - 1; i >= 0; i--){
let randomIndex = Math.floor(Math.random() * (_this.length - 1))
let temp = _this[randomIndex]
_this[randomIndex] = _this[i]
_this[i] = temp
}
return _this
}
var tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tempArray.shuffle();
console.log(tempArray);
照着上面的大佬敲了一遍,感觉randomIndex这里一直用数组的长度-1会不会好一点啊
function fn(arr) {
var newarr = arr.concat();
for (var i = 0; i < newarr.length; i++) {
var index = Math.floor(Math.random() * newarr.length);
var temp = newarr[i];
newarr[i] = newarr[index];
newarr[index] = temp;
}
return newarr;
}
第24天 如何快速让一个数组乱序,写出来
function outOfOrder(arr) {
return arr.sort(function(){ return Math.random() < 0.5 ? 1 : -1 })
}
console.log(outOfOrder([1,2,3,4,5]))
function outOfOrder(arr) {
return arr.sort(function(){ return Math.random() < 0.5 ? 1 : -1 })
}
console.log(outOfOrder([1,2,3,4,5]))
/**
- 如何快速让一个数组乱序,写出来
*/
function randomSortArr(arr){
const newArr = [];
function recursive(){
const len = arr.length;
if( arr.length > 0 ){
const randomNum = parseInt( Math.random() * len );
newArr.push( arr[randomNum] );
arr.splice( randomNum,1 );
recursive();
}
}
recursive();
return newArr;
}
console.log( randomSortArr([1,2,3,4,5,6,7,8,9,10,11,12,13,34]) )
function shuffle(arr){
return arr.sort(() => {
return Math.random() - 0.5
})
}
function shuffle2(arr){
const a = [...arr]
const res = []
while (a.length) {
const idx = Math.floor(Math.random() * a.length)
res.push(...a.splice(idx, 1))
}
return res
}
const arr = [1,2,3,4,5,6,7,8]
console.log(shuffle(arr))
console.log(shuffle2(arr))
// [ 7, 2, 1, 5, 6, 4, 3, 8 ]
// [ 2, 8, 1, 5, 3, 6, 4, 7 ]
function rd(arrayLength) {
return Math.floor(Math.random() * arrayLength);
}
//The Math.random() function returns a floating-point, pseudo-random number in the range 0 to less than 1 (inclusive of 0, but //not 1)...
const result=[];
var count=0;
function recur(pArray){
console.log(pArray);
if(result.length===pArray.length){
return ;
}
count++;
let k=rd( pArray.length );
if(pArray[k] !==null){
result.push(pArray[k]);
pArray[k] =null;
}
recur(pArray);
}
recur(arr);
console.log(count);
console.log(result );
sort()
// ES5
function randArr(arr) {
return arr.sort(function () {
return Math.random() - 0.5;
});
}
console.log(randArr([1, 2, 3, 4, 5]));
// ES6
let arr = [1, 2, 3, 4, 5];
let newArr = (arr) => arr.sort(() => Math.random() - 0.5);
console.log(newArr(arr));
let arr = [1, 2, 3, 4, 5];
let newArr = arr.sort(() => Math.random() - 0.5);
console.log(newArr);
const shuffle = arr => arr.sort(() => Math.random() - 0.5);
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(array.sort((a, b) => {
return Math.floor(Math.random() * 10) - 5;
}));
let arr6 = [1,2,3,4,5,6,7,8,9]
// 将数组乱序
function shuffle(arr) {
// 第一种 sort
// return arr.sort(() => Math.random() - 0.5)
// 第二种 洗牌
for(let i=0, len = arr.length; i<len; i++) {
let k = Math.floor(Math.random() * len)
// 交换元素
if (k != i) [arr[k], arr[i]] = [arr[i], arr[k]]
}
return arr
}
console.log(shuffle(arr6))
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let newArr = []
for (i = 0; i < arr.length; i < 10) {
let index = Math.floor(Math.random() * arr.length)
let item = arr.splice(index, 1)[0];
newArr.push(item);
}
console.log(newArr)
洗牌算法(shuffle):假设数组长度为n,生成0 ~ n-1之间的随机数random,然后将第random个元素与最后一个元素交换位置,继续生成 0 ~ n-2 之间的随机数random,将第random个元素与数组倒数第二个元素交换位置
function shuffle(arr){
let len = arr.length;
for(let i = len - 1; i > 0; i --){
let random = Math.floor(Math.random() * (i + 1));
[arr[random], arr[i]] = [arr[i], arr[random]];
}
return arr;
}
在JavaScript中,可以使用洗牌算法(Fisher-Yates算法)来快速将一个数组乱序。以下是一个实现洗牌算法的示例:
function shuffleArray(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]]; // 交换当前位置和随机位置的元素
}
return array;
}
// 示例用法
const myArray = [1, 2, 3, 4, 5];
const shuffledArray = shuffleArray(myArray);
console.log(shuffledArray); // 输出乱序后的数组
在上面的示例中, shuffleArray
函数接受一个数组作为参数,并使用洗牌算法对数组进行乱序。算法通过从最后一个元素开始,逐步向前遍历数组,每次生成一个随机索引,并将当前位置的元素与随机位置的元素进行交换。最终得到乱序后的数组。
请注意,这个算法会修改原始数组,如果不想修改原始数组,可以在函数内部创建一个新的数组并进行操作。