如何随机(洗牌)JavaScript数组?
我有这样一个数组:如何随机(洗牌)JavaScript数组?,javascript,arrays,random,shuffle,Javascript,Arrays,Random,Shuffle,我有这样一个数组: var arr1 = ["a", "b", "c", "d"]; 如何随机/洗牌?事实上的无偏洗牌算法是Fisher-Yates(又名Knuth)洗牌 看 你可以看到一个(和原来的帖子) 函数洗牌(数组){ var currentIndex=array.length,随机索引; //虽然还有一些元素需要洗牌。。。 而(0!==currentIndex){ //选择剩余的元素。。。 randomIndex=Math.floor(Math.random()*currentIn
var arr1 = ["a", "b", "c", "d"];
如何随机/洗牌?事实上的无偏洗牌算法是Fisher-Yates(又名Knuth)洗牌 看 你可以看到一个(和原来的帖子)
函数洗牌(数组){
var currentIndex=array.length,随机索引;
//虽然还有一些元素需要洗牌。。。
而(0!==currentIndex){
//选择剩余的元素。。。
randomIndex=Math.floor(Math.random()*currentIndex);
当前索引--;
//并将其与当前元素交换。
[array[currentIndex],array[randomIndex]=[
数组[randomIndex],数组[currentIndex];
}
返回数组;
}
//像这样使用
var-arr=[2,11,37,42];
洗牌(arr);
控制台日志(arr)代码>可以(或应该)使用它作为数组的原型:
克里斯托弗:
Array.prototype.shuffle = function() {
var i = this.length, j, temp;
if ( i == 0 ) return this;
while ( --i ) {
j = Math.floor( Math.random() * ( i + 1 ) );
temp = this[i];
this[i] = this[j];
this[j] = temp;
}
return this;
}
下面是Fisher-Yates的优化版本的JavaScript实现:
/* Randomize array in-place using Durstenfeld shuffle algorithm */
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
它为每个原始数组元素选择一个随机元素,并将其从下一次抽取中排除,就像从一副牌中随机选择一样
这种巧妙的排除将拾取的元素与当前元素交换,然后从剩余元素中拾取下一个随机元素,向后循环以获得最佳效率,确保简化随机拾取(它始终可以从0开始),从而跳过最后一个元素
算法运行时为O(n)
注意洗牌是就地完成的,因此如果您不想修改原始数组,请首先使用制作副本
编辑:更新至ES6/ECMAScript 2015
新的ES6允许我们同时分配两个变量。当我们想交换两个变量的值时,这尤其方便,因为我们可以在一行代码中完成。下面是使用此功能的同一函数的较短形式
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]];
}
}
使用下划线.js库。对于这种情况,方法\uuu0.shuffle()
很好。
以下是该方法的一个示例:
var _ = require("underscore");
var arr = [1,2,3,4,5,6];
// Testing _.shuffle
var testShuffle = function () {
var indexOne = 0;
var stObj = {
'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5
};
for (var i = 0; i < 1000; i++) {
arr = _.shuffle(arr);
indexOne = _.indexOf(arr, 1);
stObj[indexOne] ++;
}
console.log(stObj);
};
testShuffle();
var=require(“下划线”);
var-arr=[1,2,3,4,5,6];
//测试-洗牌
var testShuffle=函数(){
var指数=0;
var stObj={
'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5
};
对于(变量i=0;i<1000;i++){
arr=随机播放(arr);
indexOne=u0.indexOf(arr,1);
stObj[indexOne]++;
}
console.log(stObj);
};
testShuffle();
添加到@Laurens Holsts答案。这是50%的压缩
function shuffleArray(d) {
for (var c = d.length - 1; c > 0; c--) {
var b = Math.floor(Math.random() * (c + 1));
var a = d[c];
d[c] = d[b];
d[b] = a;
}
return d
};
var shuffle=函数(数组){
温度=[];
originalLength=数组长度;
对于(变量i=0;i
警告
不建议使用此算法,因为它效率低且有强偏见;见评论。它被留在这里供将来参考,因为这个想法并不罕见
本教程直截了当地解释了这些区别。Fisher-Yates的另一个实现,使用严格模式:
function shuffleArray(a) {
"use strict";
var i, t, j;
for (i = a.length - 1; i > 0; i -= 1) {
t = a[i];
j = Math.floor(Math.random() * (i + 1));
a[i] = a[j];
a[j] = t;
}
return a;
}
递归解决方案:
function shuffle(a,b){
return a.length==0?b:function(c){
return shuffle(a,(b||[]).concat(c));
}(a.splice(Math.floor(Math.random()*a.length),1));
};
新的
更短&可能更快的Fisher-Yates洗牌算法
它使用while---
按位到楼层(数字最多为10位十进制数字(32位))
移除了不必要的闭包和其他东西
脚本大小(函数名为fy):90字节
演示
*可能在除chrome之外的所有浏览器上都更快
如果你有任何问题,尽管问
编辑
是的,它更快
性能:
使用顶级投票函数
编辑
计算过多(不需要--c+1),没有人注意到
更短(4字节)和更快(测试!)
在其他地方缓存var rnd=Math.random
然后使用rnd()
也会略微提高大型阵列的性能
可读版本(使用原始版本。这比较慢,变量是无用的,比如闭包&“;”,代码本身也比较短…请阅读此内容,顺便说一句,您无法在类似上面的javascript缩微器中压缩以下代码。)
首先,看看javascript中不同排序方法的视觉对比
其次,如果您快速查看上面的链接,您会发现与其他方法相比,随机顺序
排序的性能相对较好,同时实现起来非常简单和快速,如下所示:
function shuffle(array) {
var random = array.map(Math.random);
array.sort(function(a, b) {
return random[array.indexOf(a)] - random[array.indexOf(b)];
});
}
Edit:正如@gregers所指出的,使用值而不是索引调用比较函数,这就是为什么需要使用indexOf
。请注意,此更改使代码不太适合较大的数组,因为indexOf
在O(n)时间内运行。随机化数组
var arr = ['apple','cat','Adam','123','Zorro','petunia'];
var n = arr.length; var tempArr = [];
for ( var i = 0; i < n-1; i++ ) {
// The following line removes one random element from arr
// and pushes it onto tempArr
tempArr.push(arr.splice(Math.floor(Math.random()*arr.length),1)[0]);
}
// Push the remaining item onto tempArr
tempArr.push(arr[0]);
arr=tempArr;
var arr=[“苹果”,“猫”,“亚当”,“123”,“佐罗”,“佩妮];
var n=阵列长度;var tempArr=[];
对于(变量i=0;i
我在这个问题的副本上的“作者删除”答案中发现了这个变体。与其他一些已经有很多赞成票的答案不同,这是:
实际上是随机的
不在适当的位置(因此是shuffled
名称,而不是shuffle
)
此处尚未出现多个变体
用javascript洗牌。我之所以在这里发表这篇文章,是因为使用了两个实用函数(swap和randInt),与这里的其他答案相比,该算法更加清晰
function swap(arr, i, j) {
// swaps two elements of an array in place
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function randInt(max) {
// returns random integer between 0 and max-1 inclusive.
return Math.floor(Math.random()*max);
}
function shuffle(arr) {
// For each slot in the array (starting at the end),
// pick an element randomly from the unplaced elements and
// place it in the slot, exchanging places with the
// element in the slot.
for(var slot = arr.length - 1; slot > 0; slot--){
var element = randInt(slot+1);
swap(arr, element, slot);
}
}
使用ES2015,您可以使用以下选项:
Array.prototype.shuffle = function() {
let m = this.length, i;
while (m) {
i = (Math.random() * m--) >>> 0;
[this[m], this[i]] = [this[i], this[m]]
}
return this;
}
用法:
[1, 2, 3, 4, 5, 6, 7].shuffle();
矮子
function shuffle(array) {
var random = array.map(Math.random);
array.sort(function(a, b) {
return random[array.indexOf(a)] - random[array.indexOf(b)];
});
}
var arr = ['apple','cat','Adam','123','Zorro','petunia'];
var n = arr.length; var tempArr = [];
for ( var i = 0; i < n-1; i++ ) {
// The following line removes one random element from arr
// and pushes it onto tempArr
tempArr.push(arr.splice(Math.floor(Math.random()*arr.length),1)[0]);
}
// Push the remaining item onto tempArr
tempArr.push(arr[0]);
arr=tempArr;
Array.prototype.shuffled = function() {
return this.map(function(n){ return [Math.random(), n] })
.sort().map(function(n){ return n[1] });
}
function swap(arr, i, j) {
// swaps two elements of an array in place
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function randInt(max) {
// returns random integer between 0 and max-1 inclusive.
return Math.floor(Math.random()*max);
}
function shuffle(arr) {
// For each slot in the array (starting at the end),
// pick an element randomly from the unplaced elements and
// place it in the slot, exchanging places with the
// element in the slot.
for(var slot = arr.length - 1; slot > 0; slot--){
var element = randInt(slot+1);
swap(arr, element, slot);
}
}
Array.prototype.shuffle = function() {
let m = this.length, i;
while (m) {
i = (Math.random() * m--) >>> 0;
[this[m], this[i]] = [this[i], this[m]]
}
return this;
}
[1, 2, 3, 4, 5, 6, 7].shuffle();
function arrayShuffle(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
const someArray = [1, 2, 3, 4, 5];
someArray.sort(() => Math.random() - 0.5);
/**
* 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;
};
let unshuffled = ['hello', 'a', 't', 'q', 1, 2, 3, {cats: true}]
let shuffled = unshuffled
.map((a) => ({sort: Math.random(), value: a}))
.sort((a, b) => a.sort - b.sort)
.map((a) => a.value)
function shuffle(array) {
var result = [], source = array.concat([]);
while (source.length) {
let index = Math.floor(Math.random() * source.length);
result.push(source[index]);
source.splice(index, 1);
}
return result;
}
function shuffle(array) {
var result = [], source = array.concat([]);
while (source.length) {
let index = Math.floor(Math.random() * source.length);
result.push(source.splice(index, 1)[0]);
}
return result;
}
['a','b','c','d'].map(x => [Math.random(), x]).sort(([a], [b]) => a - b).map(([_, x]) => x);
var myArr = ["a", "b", "c", "d"];
myArr.forEach((val, key) => {
randomIndex = Math.ceil(Math.random()*(key + 1));
myArr[key] = myArr[randomIndex];
myArr[randomIndex] = val;
});
// see the values
console.log('Shuffled Array: ', myArr)
//one line solution
shuffle = (array) => array.sort(() => Math.random() - 0.5);
//Demo
let arr = [1, 2, 3];
shuffle(arr);
alert(arr);
function shuffle(array) {
return array.sort(() => Math.random() - 0.5);
}