我尝试编写一些带有数组条目并随机播放顺序的javascript。它不是应该像它应该编译的那样。似乎只运行一次for循环。我错过了什么?
//random number between 1 and num
function randInt(num){
return Math.floor(num*Math.random()+1);
}
//shuffles deck (array) of any size
function shuffle(array){
var newArray = new Array();
var n = array.length;
for(i=0; i<n; i++){
var entry = randInt(array.length) - 1;
newArray[i] = array[entry]; //assigns random entry in initial array to new array
array = array.splice(entry, 1); //removes the entry that was stored into newArray
}
array = newArray;
}
答案 0 :(得分:4)
array.splice
修改array
并返回已删除的项目。您想要丢弃该元素,所以只需执行此操作而不是覆盖array
:array.splice(entry, 1);
+ 1
在randInt
中,之后- 1
看起来非常愚蠢。
var i = 0
(虽然看看我的最后一点)。[]
代替new Array()
,因为后者通常不会使用。array
:return newArray;
array
,因此您不能再循环到n
,因为每次长度减少1。您可能需要while(array.length > 0) { ... }
而不是for
循环。答案 1 :(得分:3)
您在这里遇到的根本问题是您的代码就像JavaScript是一种逐个引用的语言一样。不是;它是按值调用的。因此,函数的最后一行在语法上是正确的,但在功能上是无用的。
这是Fisher-Yates洗牌:
function fyShuffle(a) {
if (a.length < 2) return;
for (var i = a.length; --i >= 1; ) {
var j = ~~(Math.random() * (i + 1)), tmp;
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
答案 2 :(得分:0)
不需要重新发明轮子(在这种情况下是洗牌)。
function shuffle(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;
}
答案 3 :(得分:0)
为什么不将array.sort与自定义函数一起使用?
function shuffle(array) {
array.sort(function(a, b) {
return (Math.random() < 0.5) ? 1 : -1;
});
}
答案 4 :(得分:0)
Array.prototype.shuffle= function(){
var i, L= this.length;
while(--L){
i= Math.floor(Math.random()*L);
this[L]= this.splice(i, 1, this[L])
}
return this;
}
很难说使用拼接是否比直接分配更快 -
Array.prototype.shuffle= function(){
var i, temp, L= this.length;
while(--L){
i= Math.floor(Math.random()*L);
temp= this[i];
this[i]= this[L];
this[L]= temp;
}
return this;
}