I have put multiples variables within a function and I was wondering if there was any way possible in JavaScript to select a variable within that function at random. Any help is greatly appreciated. Thank you so much.
If you use an array instead of multiple variables then you can select a random element from the array:
function test() {
var values = ["test","values","go","here"],
valueToUse = values[Math.floor(Math.random() * values.length)];
// do something with the selected value
alert(valueToUse);
}
Demo: http://jsfiddle.net/XDn2f/
(Of course the array doesn't have to contain simple values like the strings I showed, you could have an array of objects, or references to other functions, etc.)
If one of your parameters is an array you can randomly select one value from it.
function myFunc(arrayInput)
{
var randomIndex = Math.floor((Math.random()*10)+1);
return (arrayInput[randomIndex]);
}
If you have N variables, then it is cleanest to put them in an array and generate a random index into that array.
var items = [1,2,3,4];
var index = Math.floor(Math.random() * items.length);
items[index] = whatever;
If you only have a couple variables, you can generate a random number and use an if/else statement to operate on the desired variable.
var a, b;
var index = Math.random();
if (index < 0.5) {
// operate on a
a = 3;
} else {
// operate on b
b = 3;
}
Related
Hi I have a JQuery object with multiple divs inside each containing text:
var object = $(<div>我</div>,<div>喜欢</div>,<div>吃</div>);
I want to copy the object and shuffle the divs inside so that when I display the new object, it will be a shuffled version of the original object. Is this possible with a JQuery object or am I going to have to store the divs in an array, and if so can someone tell me how I could achieve this?
Use a generic shuffle algorithm (e.g. the Fisher-Yates shuffle) and pass your object as the argument, e.g.
function shuffle(array) {
var m = array.length, t, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
};
var object = $('<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>');
/* use spread operator to pass the array of divs */
var shuffledArray = shuffle([...object]);
/* append divs to the body */
$('body').html($(shuffledArray));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I have only been learning javascript for 2 weeks, so apologies if my question seems weird/doesn't make sense. I'm learning the basics of arrays, and to help me learn I like to practise and play around with the code but I can't seem to figure this one out.
I've created a simple function, and wanting to call upon the function to calculate the sum of variables in an array. Here is my code below:
//functions
function simpleCalc (a,b) {
var result = a + b;
return result;
}
//array
var myArray = [12,567];
//final calculation
var total = simpleCalc([0],[1]);
alert("The total is " + total);
Can anyone please shed any light as to how I input the numbers "12" and "567" into the function parameters? The result here as it stands outputs to "01"
Thanks
You have two options:
Your option but, it is very limited to only two values.
You need to pass reference to your array elements like so (myArray[0], myArray[1])
Create new function - let's call it sumValuesInArray(), pass an array and calculate all values inside an array using for loop.
See working example here:
//functions
function simpleCalc (a,b) {
var result = a + b;
return result;
}
//array
var myArray = [12,567];
//final calculation
var total = simpleCalc(myArray[0],myArray[1]);
//alert("The total is " + total);
// OR
function sumValuesInArray(array) {
var total = 0;
for(i = 0; i < array.length; i++) {
var element = array[i];
total += element;
}
return total;
}
console.log(sumValuesInArray(myArray));
You don't specify the array but only indexes :
var total = simpleCalc([0],[1]);
So, it passes two array objects : [0] and [1].
The concatenation of them here :
var result = a + b;
has as result the 01 String.
To pass the two first elements of myArray, try it :
var total = simpleCalc(myArray[0],myArray[1]);
You need to access the array values by index. You do this using the brackets WITH the name of the array. If you pass the brackets with numbers inside, you're creating new arrays.
It should be:
var total = simpleCalc(myArray[0],myArray[1]);
I'm trying to get the function below to return the average of all elements in array1, but I keep getting null as the result. I can't seem to figure out why.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
average +=parseInt(arrayavg[answer]);
var calc = average/arrayavg.length;
return calc
};
There are a number of errors, I don't have time to point them all out, hopefully the following is sufficient:
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
I don't know why you using a function expression rather than a function declaration. It doesn't affect the issue, but is more code to write. It's also good to give variables names that express what they are for, so given that the function expects an array:
function arrayAverage(array) {
then:
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
It's not a good idea to pile all those variable declarations into the for condition, far better to separate concerns and only create variables that you need:
var total = 0;
Now iterate over the array to get the total value. The '{' brackets can be omitted, but it's clearer to include them:
for (var i=0, iLen=array.length; i<iLen; i++) {
total += array[i];
}
Now calculate the average and return it in one statement:
return total/iLen;
}
console.log(arrayAverage(array1)); // 230.375
You need to put brackets after your for loop
I was too fast to answer.
You are re-assigning the passed array to the length of the passed array.
arrayavg = arrayavg.length
this breaks everything.
in the for loop you have assigned arrayavg=arrayavg.length and in the body ,you are accessing average+=arrayavg[answer]. arrayavg is now a primitive type . it will return undefined.
And your loop condition is array1 > answer array1 is an array .you cant compare it like that.it will return false.
modified code.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
var sum=0;
for (var i=0;i<arrayavg.length;i++)
sum +=parseInt(arrayavg[i]);
return sum/arrayavg.length;
};
You are comparing a number to your array in your for loop. You want to stop the for when answer is the same as array1 length.
Also, don't change your parameter array to its length if you want to get its values in the loop.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
for (var average = 0,answer=0, len = arrayavg.length;len > answer;answer++)
average +=parseInt(arrayavg[answer]);
var calc = average/len;
return calc
};
And to call it:
arrayAverage(array1);
Your code has two problems in the for loop.
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
First thing is you set arrayavg to arrayavg's length BUT in the next line you try to read the index of the array. Well you overwrote the array with a number! Not going to happen.
Second issue you are comparing an array 'array1' to a number 'answer' . What does that check do? Not what you think it is going. You want to be checking the length, but wouldn't you want to be checking the passed in array, not the hardcoded one?
I think the other answers (particularly RobG) have covered most of it. It might help to follow a couple of standard rules (that I use) for your loops:
1) Always have the index as the first declared element, the length of the array (for caching purposes) as the second, and any other variables after them.
2) Always use brackets to separate your loop code from the code in the rest of the function. That way you know when to return your averaged product (ie after the }).
So this is my slightly rewritten code of your problem:
for (var index = 0, len = arrayavg.length, avg = 0; index < len; index++) {
avg += parseInt(arrayavg[index], 10) / len;
}
return avg;
Note also that parseInt should contain a radix (in this case 10). You can leave it out but it's good practice to always include it.
By the way, here's an alternative to your function you might find useful that uses a functional approach using reduce:
var arrayAverage = function (arr) {
return arr.reduce(function (a, b) { return a + b; }) / arr.length;
}
I have an array with a finite number of items in it. I want to randomly remove items until all the items have been used once.
Example [1,2,3,4,5]
Random number 5 is used, so I don't want that again.
Random number 2 is used, so I don't want that again.
And so on..
I could have another list of used numbers and check that the new random number is not in it, but that could take a long time when there is only 1 or two numbers left in the array out of 50.
Is there a way to remove an item from an array in javascript? Does it create a new array and would that be inefficient?
Are arrays the wrong way to do this?
EDIT: A few good answers here. I ended up randomizing the array list and then splicing the first item which is the one I took out.
Use the combination of Math.random() and splice():
var arr = [1, 2, 3, 4, 5],
i;
while ( arr.length ) {
i = Math.floor( Math.random() * arr.length );
alert( arr.splice(i, 1) );
}
Live demo: http://jsfiddle.net/simevidas/n2Bmk/
Update: You can use this function to remove a random item from your array:
function popRandomItem(arr) {
return arr.length ?
arr.splice(Math.floor(Math.random() * arr.length), 1)[0] : null;
}
So, if you have an array x, then popRandomItem(x) will remove a random item from that array and return that item. (If x is an empty array, the function will return null.)
Live demo: https://jsbin.com/wetumec/edit?js,console
You can use splice() to remove array elements.
Update
The function below lets you specify an upper and lower bound, and calling the resulting returned function will return a random number until the pool is empty, in which case it will return false (make sure you detect this with getRandom() === false).
var getRandomNumberOnce = function(lower, upper) {
var pool = [];
for (var i = lower; i <= upper; i++) {
pool.push(i);
}
return function() {
if (pool.length == 0) {
return false;
}
var randomIndex = Math.floor(Math.random() * pool.length ),
randomNumber = pool[randomIndex];
pool.splice(randomIndex, 1);
return randomNumber;
}
}
jsFiddle.
Usage
var myRandom = getRandomNumberOnce(0, 50);
myRandom(); // 4 (guaranteed to be random) :P http://xkcd.com/221/
I understand you're asking about removing elements but I'm going to go ahead and suggest an alternative way. This way does the same thing you want (getting a random element only once) but doesn't involve removing elements - well, it doesn't have to.
Essentially, randomise the order of your array rather than looking for random elements. Then work your way through the array for the random element you need. Your first random element will be at the 0 index, second random element will be at 1 index, etc.
var array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14];
array.sort(function(){ return (Math.round(Math.random())-0.5); });
for(var i=0;i<array.length;i++){
$("#list").append('<li>Random element ' + i + ': ' +array[i]);
}
Example: http://jsfiddle.net/jonathon/Re4HK/
Another question talks about randomising a JavaScript array but I just used a basic random sort as it works to illustrate the idea. You might want to look at that if you're concerned about how random your array is.
Sometimes you want a random item and don't
care if it is repeated once in a while.
Other times you want to quit when the aray is empty,
and see no repeats.
Array.prototype.getRandom= function(cut){
var i= Math.floor(Math.random()*this.length);
return cut? this.splice(i, 1): this[i];
}
I have an array var words = []//lots of different words in it. I have a Math.floor(Math.random()*words.length) that chooses a random word from the array. This is run in a loop that runs for a random number of times (between 2 and 200 times). I would like to make sure that the random numbers do not get chosen more than once during the time that that loop runs. How would you suggest doing this?
There's multiple ways of doing this.
You can shuffle the entire collection, and just grab items from one end. This will ensure you won't encounter any one item more than once (or rather, more than the number of times it occured in the original input array) during one whole iteration.
This, however, requires you to either modify in-place the original collection, or to create a copy of it.
If you only intend to grab a few items, there might be a different way.
You can use a hash table or other type of dictionary, and just do a check if the item you picked at random in the original collection already exists in the dictionary. If it doesn't, add it to the dictionary and use it. If it already exists in the dictionary, pick again.
This approach uses storage proportional to the number of items you need to pick.
Also note that this second approach is a bit bad performance-wise when you get to the few last items in the list, as you can risk hunting for the items you still haven't picked for quite a number of iterations, so this is only a viable solution if the items you need to randomly pick are far fewer than the number of items in the collection.
There are several different approaches, which are more or less effective depending on how much data you have, and how many items you want to pick:
Remove items from the array once they have been picked.
Shuffle the array and get the first items.
Keep a list of picked items and compare against new picks.
Loop through the items and pick values randomly based on the probability to be picked.
I'd shuffle the array as follows and then iterate over the shuffled array. There's no expensive array splice calls and the shuffling routine consists of swapping two values in the array n times where n is the length of the array, so it should scale well:
function shuffle(arr) {
var shuffled = arr.slice(0), i = arr.length, temp, index;
while (i--) {
index = Math.floor(i * Math.random());
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled;
}
console.log(shuffle(["one", "two", "three", "four"]));
this is how you can do it without shuffling the whole array
a = "abcdefghijklmnopq".split("");
c = 0;
r = [];
do {
var len = a.length - c;
var rnd = Math.floor(Math.random() * len);
r.push(a[rnd]);
a[rnd] = a[len - 1];
} while(++c < 5);
console.log(r);
the idea is to pick from 0..(length - step) elements and then shift the picked element towards the end.
I'd try using a map (Object literal) instead of an Array with keys being indexes:
var words = [ /* ... */ ] , map = { } , length = words.length ;
for(var n = 0 ; n < length ; n++) map[n] = words[n] ;
then make a function to pick a random entry based on the length, delete the entry (hence the index) and adjust the length:
function pickRandomEntry() {
var random = Math.floor( Math.random() * length ) ;
var entry = map[random] ;
delete map[random] ;
length-- ;
return entry ;
}
with this approach, you have to check for an undefined return value (since random might return the same number) and run the function again until it returns an actual value; or, make an array of picked indexes to filter the random numbers (which will however slow performance in case of long iteration cycles).
HTH
There are several solutions to this.
What you could do is use .splice() on your array to remove the item which is hit by words.
Then you can iterate over your array until it's empty. If you need to keep the array pristine you can create a copy of it first and iterate over the copy.
var words = ['apple', 'banana', 'cocoa', 'dade', 'elephant'];
while (words.length > 0) {
var i = Math.floor(Math.random()*words.length);
var word = words.splice(i, 1)[0];
}
Or something to that effect.
Here is a way with prime numbers and modulo that seems to do the trick without moving the original array or adding a hash:
<html>
<head>
</head>
<body>
shuffle
<div id="res"></div>
<script>
function shuffle(words){
var l = words.length,i = 1,primes = [43,47,53,59,61,67,71,73,79],//add more if needed
prime = primes[parseInt(Math.random()*primes.length, 10)],
temp = [];
do{
temp.push((i * prime) % l);
}while(++i <= l);
console.log(temp.join(','));
console.log(temp.sort().join(','));
}
</script>
</body>
</html>