【问题标题】:Random permutations for a set of numbers in JavaScript [duplicate]JavaScript中一组数字的随机排列[重复]
【发布时间】:2012-12-11 13:46:51
【问题描述】:

可能重复:
How to randomize a javascript array?

我正在用 JavaScript 编写代码,我需要在其中获取 35 个输入值,为每个输入值分配一个数组中的位置,然后将它们打乱,以便它们以不同的顺序重新排列。因此:

var sort = new Array(35);
sort[0] = document.getElementById("d1p1").value;
sort[1] = document.getElementById("d1p2").value;
// ...
// ... (till 35)
var rand1 = Math.floor(Math.random() * 35);
var rand2 = Math.floor(Math.random() * 35);
// ...
// ... (till 35)
var rsort = new Array(35);
rsort[rand1] = document.getElementById("d1p1").value;
rsort[rand2] = document.getElementById("d1p2").value;

唯一的问题是,由于 Math.floor(Math.random()*35) 不止一次地从 1-35 生成一些相同的数字(嗯,我猜这就是随机性的点),那么两个值有时会分配相同的输入框并返回 undefined。有什么想法吗?

【问题讨论】:

    标签: javascript random shuffle


    【解决方案1】:

    为了在随机排列中生成均匀分布的值,您应该这样做:

    • 从 0 到 35 中选择一个随机索引,并将第一个值与该索引交换
    • 然后从 1 到 35 中选择另一个随机索引,并将第二个值与该索引交换
    • 对所有剩余的索引 (2 - 35) 继续这样做

    这是一个潜在的实现:

     // first make a copy of the original sort array
     var rsort = new Array(sort.length);
     for(var idx = 0; idx < sort.length; idx++)
     {
         rsort[idx] = sort[idx];
     }
    
     // then proceed to shuffle the rsort array      
     for(var idx = 0; idx < rsort.length; idx++)
     {
        var swpIdx = idx + Math.floor(Math.random() * (rsort.length - idx));
        // now swap elements at idx and swpIdx
        var tmp = rsort[idx];
        rsort[idx] = rsort[swpIdx];
        rsort[swpIdx] = tmp;
     }
     // here rsort[] will have been randomly shuffled (permuted)
    

    我希望这会有所帮助。

    【讨论】:

    • 复制就像 var rsort = sort.slice() 一样简单。
    • 好点 Stefan - 给猫剥皮的方法不止一种 ;)
    【解决方案2】:

    你可以使用这个other answer改编的小功能。此外,我会使用一个类,以便更轻松地获取您的所有输入。

    function randomArray(min, max) {
      return (new Array(max-min))
        .join(',').split(',')
        .map(function(v,i){ return [Math.random(), min + i]; })
        .sort().map(function(v) { return v[1]; });
    }
    
    var inputs = document.querySelectorAll('.myinput');
    
    // Creates an array with all your input elements in random order
    var randomInputs = randomArray(0, inputs.length).map(function(n){
      return inputs[ n ];
    });
    

    演示: http://jsbin.com/uyaqed/1/edit(ctrl+enter 刷新)

    【讨论】:

    • 这是一种不好的随机洗牌方式,既低效(洗牌比排序容易)又不正确(比较函数应该与元素的总排序一致)。
    • 嗯...无法理解为什么这是一种糟糕的方式和不正确的方式。它工作正常,我之前在其他项目中使用过它并完成了这项工作。
    • @6502:在这里查看演示jsbin.com/uyaqed/1/edit
    • 抱歉,我在点击链接时感到困惑。这个算法很糟糕(就像我说的排序比洗牌更难)但如果我们假设Math.random 的精度无限(然而,这个假设是 Javascript 中最好的合理近似值),它并不是不正确的。删除了反对票。但请注意,“有效”并不意味着您有时会看到它产生了您认为正确的结果。
    • @6502:我明白你的意思了。随机性虽然是主观的,但“准确”的随机性很难实现,但这对大多数事情来说应该可以正常工作;它“看起来”是随机的。我为this plugin 制作了该脚本,它可以很好地创建“随机”图块效果。
    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2023-03-16
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多