避免使用math.random()再次出现相同的值

animations = ['fadeIn','fadeInDown','slideInUp','flipInY','bounceInLeft']; 

想象一下,每当用户点击某些东西时我都会产生随机效果,所以为了获得最佳体验,我希望用户能够产生同样的效果。 但随着

 animations[ Math.floor(Math.random() * animations.length) -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 

关注@Redu和我的评论,请在使用后将其取出,但要处理副本。

 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 } } 

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

这可以防止原始数组的切片和操作。

 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; }