I'm looking to make a list item randomizer that only displays that item once. I have a basic randomizer working that pulls from an array, but when I click the button, it just continues to loop through each item. Is there a way to get each item it only display once then stop and/or display something like "list over" once complete? My js skills are very basic...
The js randomizer code:
var techniques = [
"item 1",
"item 2",
"item 3",
"item 4",
"item 5"
]
function newTechnique() {
var randomNumber = Math.floor(Math.random() * (techniques.length));
document.getElementById('techDisplay').innerHTML = techniques[randomNumber];
}
and the html
<div id="techDisplay"></div>
<button onclick="newTechnique()">New Technique</button>
I'm also wondering if there is a better way to pull in data, like using an xml or something? I intend to have likely over 50 items in the list, which could become cumbersome in the js. Let me know and thanks in advance!
CodePudding user response:
Just shuffle the array first. This is called the 'Durstenfeld shuffle'.
To answer whether you should have the data pulled in via XML or somewhere else, I'd say consider perhaps just making a JSON file. You absolutely will not run into performance issues until you're pulling in 100's of 1000's of records, so don't even worry about performance if you're working with such a small amount of data. Personally, I usually keep a separate file that contains functions that return all the initial data I need, or you can just create a JSON file and import it as soon as you open your application.
How to randomize (shuffle) a JavaScript array?
let techniques = [
"item 1",
"item 2",
"item 3",
"item 4",
"item 5"
];
let techniquesRandom = shuffleArray(techniques);
console.log(techniquesRandom);
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
CodePudding user response:
if I understood you, you mean that you want to randomize the array items: this is the code
function shuffle(array) {
randoms = [Math.trunc(Math.random() * array.length)];
let length = array.length;
while (randoms.length != length) {
for (let i = 0; i < array.length; i ) {
r = Math.trunc(Math.random() * array.length);
if (!randoms.includes(r)) {
randoms.push(r);
}
}
}
let result = [];
for (let b = 0; b < array.length; b ) {
result.push(array[randoms[b]]);
}
return result;
}
CodePudding user response:
Here is the code for the functionality you are looking for
const techniques = [
'Currently showing item 1',
'Currently showing item 2',
'Currently showing item 3',
'Currently showing item 4',
'Currently showing item 5',
'Currently showing item 6'
];
let flags = techniques.map(() => false);
function getNotShownNumber() {
let whichItemToShow;
const allAreTrue = flags.every((v) => v === true);
if (!allAreTrue) {
let value = true;
do {
const randomNumber = Math.floor(Math.random() * techniques.length);
const alreadyShown = flags[randomNumber];
if (!alreadyShown) {
flags[randomNumber] = true;
whichItemToShow = randomNumber;
value = false;
}
} while (value);
} else {
whichItemToShow = 'Completed';
}
return whichItemToShow;
}
function newTechnique() {
const number = getNotShownNumber();
const content =
number === 'Completed' ? 'List Over' : techniques[number];
document.getElementById('techDisplay').innerHTML = content;
}
<div id="techDisplay"></div>
<button onclick="newTechnique()">New Technique</button>
CodePudding user response:
You can create a flag.
var clicked = false;
Inside newtechnique you can check if clicked is false. Then make it true. And next time techdisplay wouldn't be override.