Removing Numbers From An Array - Javascript - javascript

I am writing a script where I have to randomly generate a number from an array and then remove the number so that it cannot be generated again. What appears to be happening is that the number generated, after being spliced, is removing other numbers from my array. I assume it is being subtracted. Here is the necessary code:
var randNum = [0,1,2,3,4,5,6,7,8,9];
function clickHandler ()
{
output = randNum[Math.floor(Math.random() * randNum.length)];
console.log("This is the generated number:" + output);
randNum.splice(output);
console.log("This is the resulting array without the generated number:" + randNum);
}

You mix up value and index.
Array#splice needs a count for splicing elements. If not supplied, splice splices all items from the given index to the end.
var randNum = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function clickHandler() {
var index = Math.floor(Math.random() * randNum.length);
console.log("This is the generated number: " + randNum[index]);
randNum.splice(index, 1);
console.log("This is the resulting array without the generated number: " + randNum);
}
clickHandler();
clickHandler();

Use randNum.splice(index, 1); to remove only one number from array
If deleteCount is omitted, or if its value is larger than array.length - start (that is, if it is greater than the number of elements left in the array, starting at start), then all of the elements from start through the end of the array will be deleted
MDN

This is another way of doing it.
let numbersLeft = [0,1,2,3,4,5,6,7,8,9];
let numbersPulled = [];
function generateNumber(){
let randomNumber = randNum[Math.floor(Math.random() * randNum.length)];
return randomNumber;
}
function clickHandler () {
let numberToPull = generateNumber();
if ( numbersPulled.indexOf(numberToPull) != -1){
numbersLeft.splice(numberToTest, 0);
numbersPulled.push(numberToTest);
} else {
console.log('That number has already been pulled!');
}
}

Related

How can I randomize a number within a range and make every number have equal probability [duplicate]

This question already has answers here:
Getting a random value from a JavaScript array
(28 answers)
Closed 7 years ago.
var items = Array(523, 3452, 334, 31, ..., 5346);
How do I get random item from items?
var item = items[Math.floor(Math.random()*items.length)];
1. solution: define Array prototype
Array.prototype.random = function () {
return this[Math.floor((Math.random()*this.length))];
}
that will work on inline arrays
[2,3,5].random()
and of course predefined arrays
var list = [2,3,5]
list.random()
2. solution: define custom function that accepts list and returns element
function get_random (list) {
return list[Math.floor((Math.random()*list.length))];
}
get_random([2,3,5])
Use underscore (or loDash :)):
var randomArray = [
'#cc0000','#00cc00', '#0000cc'
];
// use _.sample
var randomElement = _.sample(randomArray);
// manually use _.random
var randomElement = randomArray[_.random(randomArray.length-1)];
Or to shuffle an entire array:
// use underscore's shuffle function
var firstRandomElement = _.shuffle(randomArray)[0];
If you really must use jQuery to solve this problem (NB: you shouldn't):
(function($) {
$.rand = function(arg) {
if ($.isArray(arg)) {
return arg[$.rand(arg.length)];
} else if (typeof arg === "number") {
return Math.floor(Math.random() * arg);
} else {
return 4; // chosen by fair dice roll
}
};
})(jQuery);
var items = [523, 3452, 334, 31, ..., 5346];
var item = jQuery.rand(items);
This plugin will return a random element if given an array, or a value from [0 .. n) given a number, or given anything else, a guaranteed random value!
For extra fun, the array return is generated by calling the function recursively based on the array's length :)
Working demo at http://jsfiddle.net/2eyQX/
Here's yet another way:
function rand(items) {
// "~~" for a closest "int"
return items[~~(items.length * Math.random())];
}
Or as recommended below by #1248177:
function rand(items) {
// "|" for a kinda "int div"
return items[items.length * Math.random() | 0];
}
var random = items[Math.floor(Math.random()*items.length)]
jQuery is JavaScript! It's just a JavaScript framework. So to find a random item, just use plain old JavaScript, for example,
var randomItem = items[Math.floor(Math.random()*items.length)]
// 1. Random shuffle items
items.sort(function() {return 0.5 - Math.random()})
// 2. Get first item
var item = items[0]
Shorter:
var item = items.sort(function() {return 0.5 - Math.random()})[0];
Even shoter (by José dB.):
let item = items.sort(() => 0.5 - Math.random())[0];
var rndval=items[Math.floor(Math.random()*items.length)];
var items = Array(523,3452,334,31,...5346);
function rand(min, max) {
var offset = min;
var range = (max - min) + 1;
var randomNumber = Math.floor( Math.random() * range) + offset;
return randomNumber;
}
randomNumber = rand(0, items.length - 1);
randomItem = items[randomNumber];
credit:
Javascript Function: Random Number Generator
If you are using node.js, you can use unique-random-array. It simply picks something random from an array.
An alternate way would be to add a method to the Array prototype:
Array.prototype.random = function (length) {
return this[Math.floor((Math.random()*length))];
}
var teams = ['patriots', 'colts', 'jets', 'texans', 'ravens', 'broncos']
var chosen_team = teams.random(teams.length)
alert(chosen_team)
const ArrayRandomModule = {
// get random item from array
random: function (array) {
return array[Math.random() * array.length | 0];
},
// [mutate]: extract from given array a random item
pick: function (array, i) {
return array.splice(i >= 0 ? i : Math.random() * array.length | 0, 1)[0];
},
// [mutate]: shuffle the given array
shuffle: function (array) {
for (var i = array.length; i > 0; --i)
array.push(array.splice(Math.random() * i | 0, 1)[0]);
return array;
}
}

Generating an array with 3 unique numbers

I'm trying to create an array with three unique random numbers between 1 and 14. I've found similar questions on Stackoverflow and used the code to help me create my existing code.
It works well most of the time, but occasionaly it will create an array with two of the same numbers. Here is the offending code:
function noDuplicates (sideRandom) {
sideArray.splice(sideRandom, 1);
let sideRandom2 = Math.floor(Math.random() * 14) + 1;
sideArray.push(sideRandom2);
console.log("I've had to add " + sideRandom2)
}
function sortNumbers(array) {
array.sort(function(a, b) {
return a - b;
});
}
document.getElementById("randomiser").addEventListener("click", function () {
for (let i = 0; sideArray.length <3; i++) {
let sideRandom = Math.floor(Math.random() * 14) + 1;
console.log(sideRandom);
if (sideArray.includes(sideRandom) === false) {
sideArray.push(sideRandom);
} else {
noDuplicates(sideRandom);
};
}
console.log(sideArray);
});
I suspect the issue is that sometimes the noDuplicates function generates the same random number as sideRandom, but I can't see a way around it. can you help?
Use set with while loop to make sure we got required number of unique random numbers
// Get unique random indexes
const random = (num, count) => {
const set = new Set();
while (set.size < count) {
set.add(Math.floor(Math.random() * num) + 1);
}
return [...set];
};
document.getElementById("randomiser").addEventListener("click", function () {
console.log(random(14, 3));
});
<button id="randomiser"> Get 3 random </button>
I take a look at your code: If there is a double you call noDuplicates and try to get a non double number but there you make some mistakes.
Why using Array#splice method? It will return the array without the first element (you don't user this result) and leave the original unchanged. So this line does anything. By the way why you want to delete the first element, youz didn't add the double random-number so there is anything do delete.
Afterwards you build another new randomnumber and push it to your array without checking. By this you get your dublettes.
Better way: If you finf a double set a flag on true and when you next add a number by this you can add your hint and reset the flag to false. So everything is one function.
document.getElementById("randomiser").addEventListener("click", function () {
let sideArray = [];
let double = false;
for (let i= 0; sideArray.length <3; i++) {
let sideRandom = Math.floor(Math.random() * 14) + 1;
console.log(sideRandom);
if (sideArray.includes(sideRandom) === false) {
if (double) {
double = false;
console.log("I've had to add " + sideRandom);
}
sideArray.push(sideRandom);
} else {
double = true;
}
}
console.log(sideArray.toString());
});
<button id='randomiser'>Click</button>
You can do this pretty easily with rando.js and slice. Plus, it's human-readable and cryptographically secure. randoSequence(1, 14) creates a shuffled array of all numbers from 1 through 14, and slice(0, 3) slices out the first three values from that shuffled array.
console.log(randoSequence(1, 14).slice(0, 3));
<script src="https://randojs.com/2.0.0.js"></script>

Javascript: Check array of numbers for number of missing numbers needed to make the array consecutive

Working on some Javascript challenges on Code Signal and I'm having an issue solving this:
Ratiorg got statues of different sizes as a present from CodeMaster for his birthday, each statue having an non-negative integer size. Since he likes to make things perfect, he wants to arrange them from smallest to largest so that each statue will be bigger than the previous one exactly by 1. He may need some additional statues to be able to accomplish that. Help him figure out the minimum number of additional statues needed.
Example
For statues = [6, 2, 3, 8], the output should be
makeArrayConsecutive2(statues) = 3.
Ratiorg needs statues of sizes 4, 5 and 7.
My approach:
Sort the array smallest to largest
Create counter variable to store number of missing numbers
Iterate through array
Subtract [i + 1] element from [i] element
If it equals 1, numbers are consecutive, if not the numbers are not consecutive (increment counter variable)
Return counter variable
Here is my code:
function makeArrayConsecutive2(statues) {
// Sorts array numerically smallest to largest
statues.sort((a, b) => a - b);
let counter = 0;
// If array only contains one number return 0
if(statues.length === 1) {
return 0;
}
/* Iterate through array, subtract the current element from the next element, if it
equals 1 the numbers are consecutive, if it doesn't equal one increment the counter
variable */
for(let i = 0; i <= statues.length -1; i++) {
if(statues[i] !== statues.length -1 && statues[i + 1] - statues[i] != 1) {
counter++;
}
console.log(statues[i]);
console.log('counter : ' + counter);
}
return counter;
}
When statues contains [5, 4, 6] the output is this:
4
counter : 0
5
counter : 0
6
counter : 1
I think the problem is when array is on the last element, in this case 6, it's attempting to look at statues[i + 1] when that element doesn't exist. I added statues[i] !== statues.length -1 to my if statement to address that but it doesn't appear to be working. What's wrong with my code and why is the final element incrementing the counter variable?
I'd approach it by building the target array which goes from the min+1 to the max-1 of the input by ones, excluding members of the input.....
function missingConseq(input) {
let min = Math.min.apply(null, input)
let max = Math.max.apply(null, input)
let result = []
for (i = min+1; i < max; i++) {
if (!input.includes(i)) result.push(i)
}
return result
}
let array = [6, 2, 3, 8]
console.log(missingConseq(array))

List array elements, one by one, with a click of a button

I am new to Javascript and working with the basics. I am wanting to create an array whose individual elements are randomly drawn, one at a time, with a click of a button, until all array elements are displayed on the screen. The code I have is almost there. But the issue is that when it runs, it always grabs 2 elements on the first button click, rather than 1. It runs well for the remaining elements. Sure would appreciate some insight to this problem. Thank you.
var myArray=['1','2','3','4','5','6','7']
var text = "";
var i;
function RandomDraw() {
for(i = 0; i < myArray.length; i+=text) {
var ri = Math.floor(Math.random() * myArray.length);
var rs = myArray.splice(ri, 1);
document.getElementById("showSplice").innerHTML = text+=rs;
//document.getElementById("showArrayList").innerHTML = myArray;
}
}
It "always" draws 2 elements because of the i+=text. Your array is small thus the loop needs 2 iteration (of cocatinating the strings to get the number i) to go over myArray.length.
First iteration:
i = 0 => 0 < myArray.length => true
prints number
Second iteration: (say '4' get choosen)
i = i + text and text = '4' => i = "04" => "04" < myArray.length => true
prints number
Third iteration: (say '3' get choosen)
i = i + text and text = '43' => i = "0443" => "0443" < myArray.length => false
loop breaks
So there is a possibility that two elements get printed. Depending on the length of the array, there could be more.
You don't need the loop, just choose a number and print it:
function RandomDraw() {
if(myArray.length > 0) { // if there still elements in the array
var ri = Math.floor(Math.random() * myArray.length); // do your job ...
var rs = myArray.splice(ri, 1);
document.getElementById("showSplice").textContent = rs; // .textContent is better
}
else {
// print a message indicating that the array is now empty
}
}
Another solution is to shuffle the array and then, on each click, pop the element from the shuffled array.
function shuffle(array) {
return array.sort(function() { return Math.random() - 0.5; });
}
var button = document.getElementById('button');
var origin = ['1','2','3','4','5','6','7'];
var myArray = shuffle(origin);
var currentValue = null;
button.onclick = function() {
currentValue = myArray.pop();
if(!!currentValue) {
console.log(currentValue);
}
}
<button id='button'>
get element
</button>
You can shuffle the array again on each click, but I think it is not necessary whatsoever...
If you're wondering about Math.random() - 0.5:
[...] Math.random is returning a number between 0 and 1. Therefore, if you call Math.random() - 0.5 there is a 50% chance you will get a negative number and 50% chance you'll get a positive number.
If you run a for loop and add these results in an array, you will effectively get a full distribution of negative and positive numbers.
https://teamtreehouse.com/community/mathrandom05
I would do it this way:
let myArray=['1','2','3','4','5','6','7']
function RandomDraw(){
const selectedIndex = Math.floor(Math.random() * myArray.length);
const selected = myArray[selectedIndex]
myArray = myArray.slice(0, selected).concat(myArray.slice(selected + 1));
return selected;
}
Every time you call RandomDraw it will return a random number, without repeating.
The way I understand it, you want to draw every items from the array after a single click. So the loop is needed.
As others have said, there are several issues in your for loop :
that i+= text makes no sense
you are looping until i reaches the length of your array, but you are splicing that array, hence reducing its length
You could correct your for loop :
function RandomDraw() {
var length = myArray.length;
var ri = 0;
for (var i=0;i<length;i++) {
ri = Math.floor(Math.random() * myArray.length);
console.log("Random index to be drawn : " + ri);
// removing that index from the array :
myArray.splice(ri, 1);
console.log("myArray after a random draw : ", myArray);
}
}
Or, you could use a while loop :
function RandomDraw() {
var ri = 0;
while (myArray.length > 0) {
ri = Math.floor(Math.random() * myArray.length);
console.log("Random index to be drawn : " + ri);
// removing that index from the array :
myArray.splice(ri, 1);
console.log("myArray after a random draw : ", myArray);
}
}

Remember last n items in jQuery

I have some code to randomly highlight one name from a list (this works - see this fiddle):
function pickRandom() {
var random = Math.floor(Math.random() * 6);
$('.stname').css('background','none').eq(random).css('background','yellow');
}
But I'd like to make sure that the same names don't come up over and over. So I intend to remember the last 3 chosen indexes as a blacklist:
var recentlyAsked = new Array();
function pickRandom() {
var random;
do {
random = Math.floor(Math.random() * 6);
} while ($.inArray(random,recentlyAsked));
recentlyAsked.push(random);
if (recentlyAsked.length >= 4) recentlyAsked.shift();
$('.stname').css('background','none').eq(random).css('background','yellow');
}
This is not working; see this fiddle. Warning: it causes the browser to hang.
Any suggestions, please?
do {
random = Math.floor(Math.random() * 6);
} while ($.inArray(random,recentlyAsked));
Runs forever because inArray returns -1 when an item is not found in the array, which is a truthy value. 0 is the only number that is a falsy value. Your array is initially empty so nothing is found.
Fix it with :
do {
random = Math.floor(Math.random() * 6);
} while ($.inArray(random,recentlyAsked) > -1);
This will stop when it returns -1(not found)
var ids=['a','b','c'];
var old=['d','e','f'];//At the beginning this will need populated with 3 random values
var ran=Math.floor(Math.random() * ids.length);
var ele=ids.splice(ran,1);
old.push(ele);
ids.push(old.shift());
highlight(ele);
Here is a slightly alternative way to do what you want. The idea is just remove chosen elements and then add it back in to the original array.
Just thought I would throw my code out there:
var randomArray = new Array(0, 1, 2, 3, 4, 5);
var pastArray = new Array();
function pickRandom() {
var random = Math.floor(Math.random() * randomArray.length);
$('.stname').css('background', 'none').eq(randomArray[random]).css('background', 'yellow');
if (pastArray.length < 3) {
pastArray.unshift(randomArray[random]);
randomArray.splice(random, 1);
} else {
pastArray.unshift(randomArray[random]);
randomArray.splice(random, 1, pastArray.pop());
}
console.log("possible values: [" + randomArray + "]");
console.log("past values: [" + pastArray + "]");
}
Values are moved back and forth from the current and past values. There is no need to prepopulate values as 'past', so it starts out truly random.

Categories

Resources