2013-10-14 1 views
4

Я использую приведенный ниже код, чтобы присвоить случайный класс (из пяти) каждому отдельному изображению на моей странице.Javascript: Случайное число из 5, не повторяется до тех пор, пока все не были использованы

$(this).addClass('color-' + (Math.floor(Math.random() * 5) + 1)); 

Это прекрасно работает, но я хочу сделать так, чтобы никогда не было двух одинаковых классов подряд.

Еще лучше было бы, если бы не было двух одинаковых строк, и он также не использовал какой-либо класс более одного раза, пока все 5 не были использованы ... Как и в, удалите каждый использованный класс из массива пока все они не будут использованы, затем начните снова, не допуская, чтобы последний из предыдущих 5 и первый из следующих 5 были одного цвета.

Надеюсь, что имеет смысл, и благодарит заранее за любую помощь.

+4

Создайте диапазон от '1' до' 5' и перетасуйте массив. – elclanrs

ответ

17

Вам необходимо создать массив возможных значений, и каждый раз, когда вы извлекаете случайный индекс из массива для использования одного из значений, вы удаляете его из массива.

Вот случайная функция общего назначения, которая не будет повторяться до тех пор, пока не будут использованы все значения. Вы можете вызвать это, а затем просто добавить этот индекс в конец своего имени класса.

var uniqueRandoms = []; 
var numRandoms = 5; 
function makeUniqueRandom() { 
    // refill the array if needed 
    if (!uniqueRandoms.length) { 
     for (var i = 0; i < numRandoms; i++) { 
      uniqueRandoms.push(i); 
     } 
    } 
    var index = Math.floor(Math.random() * uniqueRandoms.length); 
    var val = uniqueRandoms[index]; 

    // now remove that value from the array 
    uniqueRandoms.splice(index, 1); 

    return val; 

} 

Работа демо: http://jsfiddle.net/jfriend00/H9bLH/


Таким образом, ваш код будет просто так:

$(this).addClass('color-' + (makeUniqueRandom() + 1)); 

Вот объектно-ориентированная форма, которая позволит более чем один из них для использования в разных местах вашего приложения:

// if only one argument is passed, it will assume that is the high 
// limit and the low limit will be set to zero 
// so you can use either r = new randomeGenerator(9); 
// or r = new randomGenerator(0, 9); 
function randomGenerator(low, high) { 
    if (arguments.length < 2) { 
     high = low; 
     low = 0; 
    } 
    this.low = low; 
    this.high = high; 
    this.reset(); 
} 

randomGenerator.prototype = { 
    reset: function() { 
     this.remaining = []; 
     for (var i = this.low; i <= this.high; i++) { 
      this.remaining.push(i); 
     } 
    }, 
    get: function() { 
     if (!this.remaining.length) { 
      this.reset(); 
     } 
     var index = Math.floor(Math.random() * this.remaining.length); 
     var val = this.remaining[index]; 
     this.remaining.splice(index, 1); 
     return val;   
    } 
} 

Пример использования:

var r = new randomGenerator(1, 9); 
var rand1 = r.get(); 
var rand2 = r.get(); 

Работа демо: http://jsfiddle.net/jfriend00/q36Lk4hk/

+0

Если бы вы могли показать мне, как «называть это» и «добавлять индекс» к имени класса, я был бы всегда благодарен. У меня нет опыта работы с javascript, но я купил книгу на этой неделе и только начал ее сегодня, поэтому я пытаюсь это исправить. Еще раз спасибо, то, что вы разместили, уже очень полезно. – user2860129

+0

@ user2860129 - Я добавил это до конца. – jfriend00

+0

Одним из усовершенствований является сохранение исходного массива и создание копии для сращивания. Когда все участники сращиваются, сделайте еще одну копию (если требуется). – RobG

2

Вы можете сделать что-то вроде этого, используя массив и splice метод:

var classes = ["color-1", "color-2", "color-3", "color-4", "color-5"]; 
for(i = 0;i < 5; i++){ 
    var randomPosition = Math.floor(Math.random() * classes.length); 
    var selected = classes.splice(randomPosition,1); 
    console.log(selected); 
    alert(selected); 
} 
1
var used = []; 
var range = [0, 5]; 

var generateColors = (function() { 
    var current; 
    for (var i = range[0]; i < range[5]; i++) { 

     while (used.indexOf(current = (Math.floor(Math.random() * 5) + 1)) != -1) ; 
     used.push(current); 
     $(" SELECTOR  ").addClass('color-' + current); 
    } 
}); 
1

Просто объяснить мой комментарий к превосходному ответу jfriend00, вы можете hav е функция, которая возвращает элементы набора в случайном порядке, пока все не будут возвращены, а затем снова начинается, например .:

function RandomList(list) { 
    var original = list; 
    this.getOriginal = function() { 
    return original; 
    } 
} 

RandomList.prototype.getRandom = function() { 
    if (!(this.remainder && this.remainder.length)) { 
    this.remainder = this.getOriginal().slice(); 
    } 
    return this.remainder.splice(Math.random() * this.remainder.length | 0,1); 
} 

var list = new RandomList([1,2,3]); 

list.getRandom(); // returns a random member of list without repeating until all 
        // members have been returned. 

Если список может быть трудно закодированы, вы можете сохранить оригинал в затворе, например,

var randomItem = (function() { 
    var original = [1,2,3]; 
    var remainder; 
    return function() { 
    if (!(remainder && remainder.length)) { 
     remainder = original.slice(); 
    } 
    return remainder.splice(Math.random() * remainder.length | 0, 1); 
    }; 
}()); 
Смежные вопросы