Reputation: 2401
animations = ['fadeIn','fadeInDown','slideInUp','flipInY','bounceInLeft'];
Imagine I generate random effect whenever user click something, so to achieve best experience, I would want the user to have same effect. But with
animations[ Math.floor(Math.random() * animations.length) -1];
that would happens.
How to avoid same value to appear again?
Upvotes: 1
Views: 373
Reputation: 386560
I suggest to use a different method, by storing the last two selected elements and choose a different from the last selected items.
That prevent slicing and manipulation of original array.
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; }
Upvotes: 0
Reputation: 26161
Two ways that i can suggest.
.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
Upvotes: 3
Reputation: 3826
Following @Redu and my comments, take it out after you use it, but work on a copy.
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
}
}
Upvotes: 0