Reputation: 497
I have this code which adds a random class to a list. How can I avoid repeating the class name again in the list?
$(document).ready(function() {
var classes = ["col-1", "col-2", "col-3", "col-4", "col-5", "col-6"];
$("#megamenu #nav li").each(function(){
$(this).addClass(classes[~~(Math.random()*classes.length)]);
});
});
Upvotes: 0
Views: 259
Reputation: 23482
Assuming that you have as many unique classes as you have li
s, you could do this.
function shuffle(obj) {
var i = obj.length;
var rnd, tmp;
while (i) {
rnd = Math.floor(Math.random() * i);
i -= 1;
tmp = obj[i];
obj[i] = obj[rnd];
obj[rnd] = tmp;
}
return obj;
}
var classes = ["col-1", "col-2", "col-3", "col-4", "col-5", "col-6"];
shuffle(classes);
$("#megamenu #nav li").each(function() {
$(this).addClass(classes.pop());
});
.col-1 {
background-color: red;
}
.col-2 {
background-color: blue;
}
.col-3 {
background-color: yellow;
}
.col-4 {
background-color: green;
}
.col-5 {
background-color: pink;
}
.col-6 {
background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="megamenu">
<ul id="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
</div>
First we shuffle the classes
using a Fisher-Yates shuffle, we then remove an entry from classes
and assign it to a li
, this way it can not be used again.
Upvotes: 1
Reputation: 10148
Since there is no critical dependency in your application you can use sort
as a primitive shuffle:
$(document).ready(function() {
var classes = ["col-1", "col-2", "col-3", "col-4", "col-5", "col-6"];
classes.sort(function(){ return Math.random() - .5 });
$("#megamenu #nav li").each(function(){
$(this).addClass(classes.pop());
});
});
Upvotes: 0
Reputation: 6480
Many options:
splice
as already answered. blacklist
.Option 2 implementation:
$(document).ready(function () {
var classes = ["col-1", "col-2", "col-3", "col-4", "col-5", "col-6"];
var blacklist = [];
$("#megamenu #nav li").each(function () {
var index = ~~ (Math.random() * classes.length);
var currClass = classes[index ];
if(! $.inArray(currClass , blacklist )) //or you can use the array index instead of class name.
$(this).addClass(currClass );
blacklist.push(currClass );
});
});
3.use classes array as an object and put used attribute once the class has been used.
$(document).ready(function () {
var classes = {
0:{name:"col-1", used:false},
1:{name:"col-2", used:false},
2:{name:"col-3", used:false},
3:{name:"col-4", used:false},
4:{name:"col-5", used:false},
5:{name:"col-6", used:false}
};
$("#megamenu #nav li").each(function () {
var index = ~~ (Math.random() * Object.keys(classes).length);
if(classes[index].used === false))
$(this).addClass(classes[index].name);
});
});
Upvotes: 0
Reputation: 388316
Try to use splice to remove the used item from the array
$(document).ready(function () {
var classes = ["col-1", "col-2", "col-3", "col-4", "col-5", "col-6"];
$("#megamenu #nav li").each(function () {
var idx = ~~ (Math.random() * classes.length);
$(this).addClass(classes[idx]);
classes.splice(idx, 1)
});
});
Demo: Fiddle
Upvotes: 0