【问题标题】:avoid same value to appear again using math.random()避免使用 math.random() 再次出现相同的值
【发布时间】:2023-04-04 21:03:01
【问题描述】:
animations = ['fadeIn','fadeInDown','slideInUp','flipInY','bounceInLeft'];

想象一下,每当用户点击某物时,我都会产生随机效果,所以为了获得最佳体验,我希望用户也有相同的效果。但是随着

animations[ Math.floor(Math.random() * animations.length) -1];

那会发生。

如何避免相同的值再次出现?

【问题讨论】:

  • 你有 5 种效果。显示相同的值是很自然的。你能提供更多关于How to avoid same value to appear again?的细节吗?
  • 您可以为效果索引设置一个变量 i,然后将动画(或它的副本)设置为 animations.splice(i,1)。只要数组变空,你就需要从所有动画重新开始。
  • 另外你确定你想要那个-1吗?
  • 随机选择一个item,从sources数组中拼接出来,这样就不会再被选中了。 animations.splice(Math.floor(Math.random() * animations.length),1);
  • @JeremyKahan splice 将从数组中删除动画名称。

标签: javascript jquery


【解决方案1】:

我可以建议两种方法。

  1. 首先打乱数组,从索引 0 到 5 一个接一个地循环,然后根据需要循环。
  2. 选择一个随机元素并将其切出,直到数组为空,然后从备份中刷新您的数组。 (注意不要使用引用进行备份,否则您的备份数组会随着一个被拼接的数组而被删除。所以请使用.slice()

Array.prototype.shuffle = function(){
  var a = this.slice(), // don't morph the original
      i = a.length,
      j;
  while (i > 1) {
    j = ~~(Math.random()*i--);
    a[i] = [a[j],a[j]=a[i]][0];
  }
return a;
};

var album = ["photo1","photo2","photo3","photo4","photo5"];
photos = album.shuffle();
photos.forEach(p => console.log(p));

console.log("another way") // the splice way

photos = album.slice();
while (photos.length) console.log(photos.splice(Math.floor(Math.random() * photos.length),1)[0]);
!photos.length && (photos = album.slice()); // restore photos album and continue
while (photos.length) console.log(photos.splice(Math.floor(Math.random() * photos.length),1)[0]);
!photos.length && (photos = album.slice()); // restore photos album and continue

【讨论】:

    【解决方案2】:

    按照@Redu 和我的cmets,用完后把它拿出来,但在副本上工作。

    var animations = ['fadeIn', 'fadeInDown', 'slideInUp', 'flipInY', 'bounceInLeft'];
    var j;
    var tmp = animations.slice(); //copy
    
    var removed = 0;
    for (var i = 1; i < 20; i++) {
        j = Math.floor(Math.random() * tmp.length);
        console.log(tmp[j]);
        tmp.splice(j, 1);
        removed++;
        if (animations.length == removed) {
            tmp = animations.slice();
            removed = 0
        }
    }

    【讨论】:

    • remove 是做什么的?
    • 和 animations.slice() 返回与动画相同的值。那么 slice() 是什么?
    • removed 计算从 tmp 中删除了多少项目。当它们都被删除后,我们需要将 tmp 重置为所有动画并重新开始。 animations.slice 确实返回与动画相同的值,但它是一个副本,不会与原始数组混淆,如果您想在其他地方使用它以及当我想重置 tmp 并且不想拥有丢失了将其重置为的内容。
    • 很容易将所有内容放在一个循环中。在我的情况下,它必须在用户的点击事件中。
    • 我写的是循环吗?我只是在说明 19 次运行的样子。您可以适应自己的循环。
    【解决方案3】:

    我建议使用不同的方法,通过存储最后两个选定的元素并选择与最后选定的项目不同的元素。

    防止对原始数组进行切片和操作。

    function Random(array) {
        var last = [];
        this.next = function () {
            var r;
            do {
                r = Math.floor(Math.random() * array.length);
            } while (~last.indexOf(r))
            last.length === 2 && last.shift();
            last.push(r);
            return array[r];
        }
    }
    
    var animations = ['fadeIn', 'fadeInDown', 'slideInUp', 'flipInY', 'bounceInLeft'],
        random = new Random(animations),
        i;
    
    for (i = 0; i < 15; i++) {
        console.log(random.next());
    }
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 这更干净。但是~ 是做什么的呢?
    • 我也没有收到这条线last.length === 2 &amp;&amp; last.shift();
    • ~ 是按位非运算符,它是检查!== -1 的简写形式。更多here。第二个是if (last.length === 2) { last.shift(); } 的缩写形式。
    猜你喜欢
    • 2015-08-13
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多