Random Select Array Item Without Duplicates Without Removing Items (JavaScript)
I have seen many questions concerning randomly selecting array items without repeating. However, most of them are answered by using the splice method. But this removes items. I ha
Solution 1:
I don't get very well what you're trying to achieve, but here's one way I'd get random items once
var letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"];
var getRandom = (function (array) {
var notGivenItems = array.map(function (el) {return el;}),
var getIndex = function () {
return Math.floor(Math.random() * notGivenItems.length);
};
return function () {
if (notGivenItems.length === 0) {
return;
}
return notGivenItems.splice(getIndex(), 1)[0];
};
})(letters); // items, in your case
getRandom(); // some letter
getRandom(); // some other letter
...
getRandom(); // different letters until all are given
// if the method is called more times than the array length it'll return undefined
EDIT: Improved performance due to @JLRishe comment
Solution 2:
Try
var items = []
, res = null
, dfd = new $.Deferred()
, processItems = function (item) {
var index = $.inArray(item, items);
console.log("random number: " + index);
$("<div />", {
"class": "TitleText",
"html": $(item).children().find("author_name")[0].innerHTML,
"data-index": index
})
.add("<br />")
.add(
$("<div />", {
"class": "Image",
"data-index": index,
"html": $("<img />", {
"class": "Image",
"data-index": index,
"src": $(item).children()
.filter("media\\:content")
.children("media\\:thumbnail")
.attr("url") + "?" + $.now(),
"width": "145"
})
})
)
.appendTo(".items")
}
, loadXML = function() {
return $.post("/echo/xml/", {xml:xml}, "xml")
.then(function(xml) {
$(xml.documentElement)
.find("item")
.each(function(i, el) {
items.push(el)
});
return items
})
};
loadXML()
.then(function(data) {
$.each(data, function(i, item) {
setTimeout(function() {
// select different randomly selected items,
// without repetition
processItems(item); ++res;
if (res === data.length) {
dfd.resolve(res + " items processed");
}
}, 1 + Math.floor(Math.random() * 25));
});
return $.when(dfd, data)
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown)
})
.then(function(msg, data) {
console.log(msg, data)
});
Solution 3:
If you want to go through an array in random order without modifying the original array:
- Make a copy of the array with
ary.slice()
(this will copy the array, but not its values if they are objects). - Shuffle the copy.
- Iterate through the copy.
var items = ["a", "b", "c", "d", "e", "f", "g"];
var copy = getShuffledCopy(items);
copy.forEach(function (el) {
console.log(el);
});
function getShuffledCopy(ary){
var copy = ary.slice();
shuffle(copy);
return copy;
}
function swap(ary, pos1, pos2) {
var tmp = ary[pos1];
ary[pos1] = ary[pos2];
ary[pos2] = tmp;
}
function shuffle(ary){
// Fisher-Yates shuffle
for(var i = ary.length - 1; i >= 1; i -= 1) {
swap(ary, Math.floor(Math.random() * i), i);
}
}
Post a Comment for "Random Select Array Item Without Duplicates Without Removing Items (JavaScript)"