【问题标题】:Javascript Random problem?Javascript 随机问题?
【发布时间】:2010-12-02 02:32:35
【问题描述】:
var swf=["1.swf","2.swf","3.swf"];
var i = Math.floor(Math.random()*swf.length);

alert(swf[i]); // swf[1]  >> 2.swf

本例,随机输出One号码。

如何随机输出two different numbers

【问题讨论】:

  • 请说明您要完成的工作。如果您需要两个随机数,您可以再次执行相同的代码。没有?
  • 我想要 2 个不同的数字 swf

标签: javascript random


【解决方案1】:
var swf = ['1.swf', '2.swf', '3.swf'],

// shuffle
swf = swf.sort(function () { return Math.floor(Math.random() * 3) - 1; });

// use swf[0]
// use swf[1]

尽管上面应该可以正常工作,但为了学术上的正确性和最高的性能和兼容性,您可能希望像这样改组:

var n = swf.length;
for(var i = n - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var tmp = swf[i];
    swf[i] = swf[j];
    swf[j] = tmp;
}

感谢 tvanfosson 和 Fisher/Yates。 :)

【讨论】:

  • 也许我遗漏了什么,但那 3 应该是 this.length 吗?
  • @alex 不。它只是随机返回 -1、0 或 1 到随机 sort 数组。 developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
  • @deceze 啊,明白了 :) 感谢您的澄清。也很干净,所以+1
  • 我通常希望排序的比较函数是确定性的。让它不是确定性的意味着你冒着让你的排序不终止的风险——因为它可能决定继续交换两个条目,尽管在实践中我怀疑它会发生。最好使用 Fisher-Yates (bit.ly/eR3325) 之类的东西来洗牌,没有这个问题。
  • @tvanosson 很有趣。我没有考虑过这一点。
【解决方案2】:

您可以使用 splice 删除选定的元素,然后简单地随机选择另一个。以下将原始数组保持不变,但如果没有必要,您可以使用原始数组并省略副本。显示使用循环来演示如何选择任意次数,直到原始数组的大小。

var swf=["1.swf","2.swf","3.swf"];
var elementsToChoose = 2;
var copy = swf.slice(0);
var chosen = [];

for (var j = 0; j < elementsToChoose && copy.length; ++j) {
   var i = Math.floor(Math.random()*copy.length);
   chosen.push( copy.splice(i,1) );
}

for (var j = 0, len = chosen.length; j < len; ++j) {
   alert(chosen[j]);
}

【讨论】:

    【解决方案3】:

    我更喜欢这种方式,因为边界是已知的(你没有得到一个随机数并比较你已经拥有的。它可以循环 1 或 1000 次)。

    var swf = ['1.swf', '2.swf', '3.swf'],
        length = swf.length,
        i = Math.floor(Math.random() * length);
        firstRandom = swf[i];
    
    // I originally used `delete` operator here. It doesn't remove the member, just
    // set its value to `undefined`. Using `splice` is the correct way to do it. 
    swf.splice(i, 1);
    length--;
    
    var j = Math.floor(Math.random() * length),
        secondRandom = swf[j];
    
    
    alert(firstRandom + ' - ' + secondRandom);
    

    Patrick DW 告诉我delete 运算符只是将值保留为undefined。我做了一些谷歌搜索并想出了这个替代解决方案。

    请务必查看Tvanfosson's answerDeceze's answer 以获得更清洁/替代的解决方案。

    【讨论】:

    • delete 不压缩数组。它将值替换为undefined。所以你最终可以得到"1.swf - undefined"
    • @alex - 用解释注释掉 delete 行,并将其替换为 swf.splice(i,1);
    • @deceze 好吧,我进行了编辑,引用了其他两个解决方案,并链接并投票赞成。还有什么我可以做的吗? :)
    • @alex - 你有list.splice(... 它应该是swf.splice(...。你不想要= 赋值,因为.splice() 修改了原始数组。如果您执行swf = swf.splice(...,那么swf 将等于被删除的项目。
    • 1.swf - 1.swf1.swf - undefined
    【解决方案4】:

    这就是我要求两个数字不同的方法(可能会更好地回答)

    var swf=["1.swf","2.swf","3.swf"]; var i = Math.floor(Math.random()*swf.length); 变量 j; 做 { j = Math.floor(Math.random()*swf.length); } 而 (j === i); 警报(swf[i]); 警报(swf[j]);

    编辑:应该是j===i

    【讨论】:

    • 数组越大,越接近选择所有元素,所需的时间就越长。使用 Fisher-Yates 洗牌并选择前 N 个条目可能是最好的一般答案。
    • 该死,只要找出导致代码完全无用的错误。已更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 2011-08-02
    • 2010-11-14
    相关资源
    最近更新 更多