【问题标题】:Randomizing elements in an array?随机化数组中的元素?
【发布时间】:2010-10-23 06:31:16
【问题描述】:

我为我的一位艺术家朋友创建了一个网站,她希望布局保持不变,但她也希望将她制作的新画作混合到当前布局中。所以我在主画廊页面上有 12 个缩略图 (thumb1 - thumb12) 和 18 个图像 (img1 - img18) 来放置

我想到的方法是创建一个包含所有图像的数组,将其随机化,然后简单地刮掉前 12 个图像并将它们加载到拇指槽中。另一种方法是从数组中随机选择 12 个图像。在第一种情况下,我找不到随机化数组元素的方法。在后一种情况下,我无法思考如何防止图像多次加载,除了使用第二个数组,这似乎非常低效和可怕。

顺便说一句,我正在用 Javascript 完成所有这些操作。

【问题讨论】:

标签: javascript algorithm arrays shuffle


【解决方案1】:

您应该实现Fisher-Yates shuffle(也称为 Knuth shuffle)。

看看here提供的出色答案。

【讨论】:

    【解决方案2】:

    您的第一种方法会奏效。只需洗牌 18 个元素并取前 12 个。

    【讨论】:

      【解决方案3】:

      我前段时间写了这篇文章,它恰好适合您正在寻找的内容。我相信 ojblass 指的是 Fisher-Yates shuffle:

      Array.prototype.shuffle = function() {
         var i = this.length;
         while (--i) {
            var j = Math.floor(Math.random() * (i + 1))
            var temp = this[i];
            this[i] = this[j];
            this[j] = temp;
         }
      
         return this; // for convenience, in case we want a reference to the array
      };
      

      请注意,修改 Array.prototype 可能被认为是错误的形式。您可能希望将其实现为将数组作为参数的独立方法。无论如何,要完成它:

      var randomSubset = originalArray.shuffle().slice(0,13);
      

      或者,如果您不想实际修改原件:

      var randomSubset = originalArray.slice(0).shuffle().slice(0,13);
      

      【讨论】:

      • 请注意,内部循环是提到的 Fisher-Yates shuffle。外循环正在进行多次洗牌。 (并不是说这有什么问题。)
      • 请注意您的“迭代器”循环。据说Fisher-Yates shuffle 是无偏的,这意味着每个排列都是同样可能的。多次混合数组绝不“意味着更好的混合”。
      • 即使随机数的分布极不均匀?无论如何,我还是把那部分编辑掉,因为它混淆了问题的答案,正如比尔指出的那样。
      • 顺便说一句,第 4 行缺少分号。
      • 在某些情况下这个函数会导致内存泄漏,但大多数情况下都有效
      【解决方案4】:

      我最近自己也遇到了这个问题。这里的帖子有帮助:http://waseemsakka.com/2012/02/14/javascript-dropping-the-last-parts-of-an-array-and-randomizing-the-order-of-an-array/

      基本上,从随机化你的数组开始:

      thumbs.sort(function(a, b) {
           return Math.random() - 0.5;
      })
      

      这将随机化 18 个元素的顺序。然后只保留前 12 个元素,您只需删除最后 6 个:

      thumbs.length = 12;
      

      【讨论】:

      • 我见过的大多数排序函数都要求比较函数是一致的,如果不是,则结果是未定义的。我可以想象随机结果将排序函数扔进一个无限循环,如果它继续重新排列它认为它具有正确顺序的项目(尽管这在实践中可能不会发生)。
      猜你喜欢
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2013-11-14
      • 2019-01-31
      • 1970-01-01
      • 2019-02-21
      • 2013-06-17
      相关资源
      最近更新 更多