I want to pick a random element from an array without repeating, but an error occurred: Cannot read properties of undefined (reading 'sound').
Here's my code:
var words = [
{ word: 'major', sound: 'major.mp3'},
{ word: 'apply', sound: 'apply.mp3'},
{ word: 'blue', sound: 'blue.mp3' },
{ word: 'cat', sound: 'cat.mp3' },
{ word: 'class', sound: 'class.mp3'},
{ word: 'code', sound: 'code.mp3' },
{ word: 'cook', sound: 'cook.mp3' },
{ word: 'daisy', sound: 'daisy.mp3'},
{ word: 'ease', sound: 'ease.mp3' },
{ word: 'idea', sound: 'idea.mp3' }
];
var randomWord = words[Math.floor(Math.random() * words.length - 5)]; // just added - 5 here
var audio = new Audio();
var playBtn = document.getElementById("play-button");
var guessBtn = document.getElementById("guess-button");
var nextBtn = document.getElementById("next-button");
var correct = document.getElementById("correct");
var incorrect = document.getElementById("incorrect");
playBtn.addEventListener("click", function() {
audio.src = randomWord.sound;
audio.play();
var name = words.splice(randomWord,1); // just added
words.push(name); // just added
})
guessBtn.addEventListener("click", function() {
var inputBox = document.getElementById("input-box").value;
if (inputBox == randomWord.word) {
correct.innerHTML = "Correct!"
}
else {
incorrect.innerHTML = "Incorrect"
}
})
nextBtn.addEventListener("click", function() {
location.reload();
})
The audio played smoothly until I attempted to make it not repeat. Am I doing it wrong?
2 Answers 2
words[Math.floor(Math.random() * (words.length - 1))];
I think you need to use like this.
because Math.floor(Math.random() * words.length - 5) can be less than 0
1 Comment
You may consider : 1) building an array of indexes from 0 to words.length, 2) picking a random index 3) getting a word using the random index (the word will be random) 4) deleting the random index to avoid repetitions. This way, you no dot not need to delete your words and your random index will always be valid.
//----------New code-----------------
var indexes = []
for (let i=0; i<words.length; i++) {
indexes.push(i)
}
//-----------------------------------
playBtn.addEventListener("click", function() {
//get a random index value
let randomIndex = Math.floor((Math.random()*words.length))
//Get your randomword here, using the random index
var randomWord = words[randomIndex];
//Delete the index so it will not repeat
indexes.splice(randomIndex,1)
//This is your code below
audio.src = randomWord.sound;
audio.play();
//var name = words.splice(randomWord,1); // delete this!
words.push(name); // just added >> is this required?
})
words, you're not doing it correctly. Check out this section of the relevant docs.words.length -5, of course you do realize this will only randomize up to 5.