Maria Jane
Maria Jane

Reputation: 2401

avoid same value to appear again using math.random()

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

Answers (3)

Nina Scholz
Nina Scholz

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

Redu
Redu

Reputation: 26161

Two ways that i can suggest.

  1. First shuffle the array and go one by one from index 0 to 5 and then loop as much as you like.
  2. Pick a random element and slice it out up until the array is empty and then refresh your array from a back up. (be careful not to back up with a reference or your backup array gets deleted along with the one gets spliced. so use .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

Jeremy Kahan
Jeremy Kahan

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

Related Questions