我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
我有一个这样的数组:
var arr1 = ["a", "b", "c", "d"];
我如何随机化/打乱它?
当前回答
使用生成器功能的ES6压缩代码*
这是通过从未屏蔽阵列的副本中随机移除项目,直到没有剩余项目。它使用新的ES6生成器功能。
设arr=[1,2,3,4,5,6,7]函数*洗牌(arr){arr=[…arr];而(arr.length)产生arr.splice(Math.random()*arr.length|0,1)[0]}console.log([…shuffle(arr)])
或者,使用ES6和拼接:
设arr=[1,2,3,4,5,6,7]let shuffled=arr.reduce(([a,b])=>(b.push(…a.splice(Math.random()*a.length |0,1)),[a,b]),[[…arr],[]])[1]console.log(混洗)
或者,ES6索引交换方法:
设arr=[1,2,3,4,5,6,7]let shuffled=arr.reduce((a,c,i,r,j)=>(j=数学随机()*(a.length-i)|0,[a[i],a[j]]=[a[j],a[i]],a),[…arr])console.log(混洗)
其他回答
对CoolAJ86答案的简单修改,不修改原始数组:
/**
* Returns a new array whose contents are a shuffled copy of the original array.
* @param {Array} The items to shuffle.
* https://stackoverflow.com/a/2450976/1673761
* https://stackoverflow.com/a/44071316/1673761
*/
const shuffle = (array) => {
let currentIndex = array.length;
let temporaryValue;
let randomIndex;
const newArray = array.slice();
// While there remains elements to shuffle...
while (currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// Swap it with the current element.
temporaryValue = newArray[currentIndex];
newArray[currentIndex] = newArray[randomIndex];
newArray[randomIndex] = temporaryValue;
}
return newArray;
};
使用Ramda的功能解决方案。
const {map, compose, sortBy, prop} = require('ramda')
const shuffle = compose(
map(prop('v')),
sortBy(prop('i')),
map(v => ({v, i: Math.random()}))
)
shuffle([1,2,3,4,5,6,7])
// Create a places array which holds the index for each item in the
// passed in array.
//
// Then return a new array by randomly selecting items from the
// passed in array by referencing the places array item. Removing that
// places item each time though.
function shuffle(array) {
let places = array.map((item, index) => index);
return array.map((item, index, array) => {
const random_index = Math.floor(Math.random() * places.length);
const places_value = places[random_index];
places.splice(random_index, 1);
return array[places_value];
})
}
使用生成器功能的ES6压缩代码*
这是通过从未屏蔽阵列的副本中随机移除项目,直到没有剩余项目。它使用新的ES6生成器功能。
设arr=[1,2,3,4,5,6,7]函数*洗牌(arr){arr=[…arr];而(arr.length)产生arr.splice(Math.random()*arr.length|0,1)[0]}console.log([…shuffle(arr)])
或者,使用ES6和拼接:
设arr=[1,2,3,4,5,6,7]let shuffled=arr.reduce(([a,b])=>(b.push(…a.splice(Math.random()*a.length |0,1)),[a,b]),[[…arr],[]])[1]console.log(混洗)
或者,ES6索引交换方法:
设arr=[1,2,3,4,5,6,7]let shuffled=arr.reduce((a,c,i,r,j)=>(j=数学随机()*(a.length-i)|0,[a[i],a[j]]=[a[j],a[i]],a),[…arr])console.log(混洗)
事实上的无偏洗牌算法是Fisher Yates(又名Knuth)shuffle。
你可以在这里看到一个很棒的可视化效果(以及链接到此的原始帖子)
函数洗牌(数组){let currentIndex=array.length,randomIndex;//而还有一些元素需要洗牌。while(currentIndex!=0){//拾取剩余的元素。randomIndex=数学地板(Math.random()*当前索引);当前索引--;//并将其与当前元素交换。[array[currentIndex],array[randomIndex]]=[array[randomIndex],array[currentIndex]];}返回数组;}//如此使用var arr=[2,11,37,42];洗牌(arr);控制台日志(arr);
有关所用算法的更多信息。