I have the following task - there is an array of some items. I use random, get item number, write item's value in div and delete element with item number from array.
e.g.
array = (1,2,3)
random = 2
div = 3
delete from array = (1,2)
looping, etc
So I wrote the following script:
window.onload = function () {
var verb_array = new Array (1,2,3)
var random_verb_array = Math.floor(Math.random() * (verb_array.length - 0+0)) + 0;
var random_verb_array_2 = verb_array[random_verb_array];
var show = document.getElementById("wuza").innerHTML = random_verb_array_2;
delete verb_array[random_verb_array];
var test = document.getElementById("huza").innerHTML = '<Br><Br>' + verb_array
}
<!DOCTYPE html>
<div id="wuza"></div>
<div id="huza"></div>
Item has no value in array, but it's position still remains. How can I avoid it and finally total wipe it from the array?
You're probably looking to use splice.
verb_array.splice(random_verb_array, 1);
So assuming random_verb_array is the random index you've come up with, it'll remove 1 (second parameter) from the given index (first parameter).
Learn more about Array.splice()
Related
I have made a random quiz through javascript and HTML, the questions are in a JSON file, but when I run the quiz it repeats some of the questions multiple times, how do I make it that no questions are repeated.
function renderQuestion(){
let index = Math.floor(Math.random() * availableQuestions.length);
runningQuestion = availableQuestions[index];
availableQuestions.pop(index);
let q = questions[runningQuestion];
question.innerHTML = "<p>"+ q.question +"</p>";
qImg.innerHTML = "<img src="+ q.imgSrc +">";
choiceA.innerHTML = q.choiceA;
choiceB.innerHTML = q.choiceB;
choiceC.innerHTML = q.choiceC;
}
You are trying to remove an object from an array by using
pop(index).
This is not possible since pop will always remove the last element in the array (and does not accepts any parameters!).
Use Array.prototype.splice instead:
availableQuestions.splice(index, 1); // Remove 1 element at specific index
you could push the "index" into an array, like
const usedQuestions = [];
And then when u create a new index look through the "usedQuestions" index to not use them again.
Array.pop does not accept a parameter, passing the index is not doing anything here. It is simply popping the last element from the array.
Let's say you have question array qa = [a, b, c, d, e].
You generate a random index (index = 2) and set running question to that index (runningQuestion = qa[2], => runningQuestion = 'c'). You then pop an element and the array becomes qa = [a, b, c, d].
On the next function call, it is still possible to retrieve the question c.
I recommend the following approaches
Randomize the array, and iterate over them
Instead of pop, use splice
Trying to make Bingo game with Javascript. Need to generate random, non-repetitive values (not integers) from an array and display what number is generated. Each value should be generated ONLY ONCE until the game is reset.
I've tried just trying to generate random element from the original Set() that the values are located in, but that will still result in repeated numbers being called. I'm currently trying to implement the Fisher-Yates/Durstenfeld shuffles, but those do not display ANY result in my HTML.
<head>
<title>BINGO</title>
</head>
<body>
<div id="bingo">
<script>
let numbers = new Set()
.add("B1")
.add("B2")
.add("B3")
.add("B4")
.add("B5")
.add("B6")
.add("B7")
.add("B8")
.add("B9")
.add("B10");
let called = Array.from(numbers);
let display = new Array();
function getRandomNum()
{
function rando()
{
for (let i = called.length - 1; i > called.length; i++)
{
const j = Math.floor(Math.random() * called.length);
const number = called[i];
called[i] = called[j];
called[j] = number;
return number;
let show = called[Math.floor(Math.random() * called.length)];
return show;
}
let index = rando();
document.getElementById('bingo').innerHTML = index;
display.push(index);
document.getElementById('bingo').innerHTML = display[0];
}
}
</script>
</div>
<div id="button">
<button onclick="getRandomNum()">Random Number</button>
</div>
</body>
</html>
Here, I was trying to shuffle the original array, pick a random element from that array to display, display the element, then add it to another array that will display what numbers were called
Once you call a number, remove it from your array. That way when you shuffle the array and/or randomize the array index, you are guaranteed to never get a duplicate.
This means either recreating the array or creating a new duplicate array before every game.
Having a "called" array to keep track of what's been called is still necessary, but won't guarantee against duplicates trying to be called, as you're seeing.
Seen this question a lot, but cannot find something that's what i'm looking for.
onClick I push an item to an array I have, however, if there's 3 items in my array I don't want to be able to push items anymore.
var selectedData = [];
I set my empty variable.
var index = selectedData.indexOf(3);
I then get the index of my array which is 3
if (index > 3) {
selectedData.splice(index, 1);
}
Then within my if statement I say, if my index which is 3, is bigger then 3, then splice at index and remove one.
selectedData.push(TheThing);
I then push TheThing to my array if the if statement above isn't true.
However, I have a variable var arrayLength = selectedData.length; that grabs the length, and when I console log it, it starts at 0 and splices items anything after 4. Not 3.
Any idea what i've done wrong or misunderstood?
Thanks
More full example of my code
var selectedData = [];
myElement.on('click', function() {
var index = selectedData.indexOf(3);
if (index > 3) {
selectedData.splice(index, 1);
}
var arrayLength = selectedData.length;
console.log(arrayLength, 'the length');
});
So in short, onClick check my array and remove anything after the third that gets added into my array.
Do you want this to behave as a stack or a queue?
So your code here:
var index = selectedData.indexOf(3);
Is not grabbing the 3rd index - its grabbing the first index where it sees 3, or -1 if it doesn't. Replace your if statement with,
if (selectedData.length > 3) {
selectedData.pop() // removes last element (stack)
// or
selectedData = selectedData.slice(1) //remove first element (queue)
}
I think you need to try var arrayLength = selectedData.length -1;
You start at 0 like a normal array, but don't you start with an empty array?
Plus when you use .length, it returns the true count of the array or collection not a 0 index.
`
you can override push() method of your array like this:
var a = [];
a.push = function(){}
or like this
a.push = function (newEl){
if(this.length <3){
Array.prototype.push.call(this, newEl)
}
}
This is not complete example because push() can take many arguments and you should to handle this case too
var index = selectedData.indexOf(3); simply give you the index of the element of the array that has value 3
Example
selectedData = [ 0, 3 , 2];
alert( selectedData.indexOf( 3 ) ); // this will alert "1" that is the index of the element with value "3"
you can use this scenario
var selectedData = [];
myElement.on('click', function() {
//if selectedData length is less than 3, push items
});
This could work.
myElement.on('click', function() {
if(selectedData.length > 3){
selectedData = selectedData.splice(0, 3);
}
console.log(selectedData.length, 'the length');
});
I currently have the following code that looks at an unordered list and selects a random item. I want to make sure the same 'li' doesn't get selected twice in a row, or even better, don't select a repeat li until all of them have been selected.
var list = $('#headshots li:visible').toArray();
var elemlength = list.length;
var randomitem = list[Math.floor(Math.random() * elemlength)];
Full code:
function sawpHomepageAgencyHeadshots() {
var fullList = [1,2,3,4,5,6,7,8,9,10];
window.setInterval(function(){
var random = fullList.slice(0).sort(function() {
return .5 - Math.random();
});
$('#headshots li').each(function() {
var i = parseInt($(this).css('background-image').replace(/\D+/, ''));
random = $.grep(random, function(value) { return value != i; });
});
var list = $('#headshots li:visible').toArray();
var elemlength = list.length;
var randomitem = list[Math.floor(Math.random()*elemlength)];
$(randomitem).css({'background-image': 'url("' + absoluteDomainPath + 'images/headshots/headshot-' + random[0] + '.jpg")'});
}, 3000);
}
Added fiddle: http://jsfiddle.net/MBP2t/
remove the random item from the list variable, then it can not be selected again.
Take a look at this fiddle where I use an interval to select each item randomly.
http://jsfiddle.net/ghcNM/
var list = $('#headshots li:visible');
var loop = setInterval(doit, 500);
function doit(){
if(list.length){
randomitem = list.splice(Math.floor(Math.random() * list.length), 1)
$(randomitem).css('background', '#ff0000');
}else{
clearInterval(loop);
}
}
You need to maintain state somewhere in your application, so there are two basic options here:
Do it in memory:
Keep an array of visited items, then, when you pull an item, check if it's in the list you've already seen. If it's not, add it to the list. If it is, randomly pick again.
Do it in the DOM:
Do you search for a node like this: $('#headshots li:visible').not('.seen')
After you've found an item, do item.addClass('seen') to mark it as seen, then continue.
Once your jQuery selector returns no values, you can remove the seen class from all elements.
For what it's worth, the second option is pretty gross.
Can you please let me know how I can select a number randomly from a list and also remove it from the array for the next time?
For example I have an array as:
var items = new Array( 2,3,4,5,6,7,8,9,10 );
now I would like to pick one item when a Pick button pushed and add the picked value to a div and also remove the picked item from the array so in next Pick button push it wont be there until to select all of items.
Thanks for your time
Array.splice()
var items = ["a","b","c","d"];
var randomIndex = Math.floor(Math.random() * items.length);
var randomItem = items.splice(randomIndex, 1)[0];
console.log("random item: %o", randomItem);
console.log("remaining items: %o", items);
If shuffling the array doesn't matter :
items.sort(function() { return 0.5 - Math.random();}).pop();
FIDDLE
EDIT:
I should probably have been a little clearer as the fiddle doesn't really take advantage of the shuffling.
The array only needs to be shuffled once to make it random, after that there is no reason to shuffle it again, just pop of the last value:
var items = new Array( 2,3,4,5,6,7,8,9,10 );
items.sort(function() { return 0.5 - Math.random();})
$('#test').on('click', function() {
var ran = items.pop();
alert(ran ? ran : 'No more numbers in array');
});
JSPERF
JSFIDDLE