Randomly selecting unique items from an array with Javascript - javascript

I know that there have been a lot of similar questions and I went through most of them. The code that is closest to what I'm trying to achieve is this one.
I have a list of people in each column (which represent a day). for the sake of this question let's assume it's 8 people in each column. I need to randomly select 5 unique people names. I've used splice() to delete the selected item from the array to make sure that it is not selected twice. I'm new to the coding and I think I'm doing some basic mistake as the splice works for the 1st loop and then the array goes back to the original one. Can you, please, help to identify my mistake?
for (var x = 0; x < 5; x++) {
var sourceArray = ss.getRange(49,j+5,8,1).getValues();
var gg = Math.floor(Math.random()*sourceArray.length);
var pickedHLA = sourceArray[gg];
sourceArray.splice(gg, 1);
var HLAselect = ss.getRange(30+x,j+5,1,1)
HLAselect.setValue(pickedHLA);

In your for loop you are redefining the sourceArray during each iteration - you need to define this outside the loop, then do your work to randomly select and remove from the array:
var sourceArray = ss.getRange(49,j+5,8,1).getValues(); //establish full list of people
for (var x = 0; x < 5; x++) {
var gg = Math.floor(Math.random()*sourceArray.length); //get random index
var pickedHLA = sourceArray[gg]; //get random person via random index
sourceArray.splice(gg, 1); //remove random person from full list of people
var HLAselect = ss.getRange(30+x,j+5,1,1)
HLAselect.setValue(pickedHLA);
}

The way you do this is actually quite simple, all it requires a few lines of code:
var arr = ["Cheese", "Purple", "List", "1", "2", "3", "4", "5"];
function random() {
var randomNumber1 = parseInt(Math.random() * arr.length);
var random = arr[randomNumber1];
alert(random);
}
<button onClick="random()">Click Me</button>
There you go!

Related

How do I get an array name out of a javascript array? Possibly a syntax issue - Noob

I am creating a program in a which a video plays of a person speaking and chunks of the text appear in a div as the words are spoken with a translation. I am trying to write a javascript function to make that happen. Basically, I am changing the visibility of the div's with "setTimeout" so the text is revealed at the right time.
I have these 3 arrays
var invite =["itimes", "idivs"]; //names of 2 arrays which contain the info for the "invite" text block
var itimes =["0", "642", "950", "2555", "1113"]; //times in msec when text should be revealed
var idivs = ["speech_bubble", "i1", "i2", "i3", "i4"]; //divs to be revealed
These are the 2 functions I have written to cause the text to be revealed
function reveal(){ //change visibility of div name retrieved
var textchunk = "invite"
var divs = textchunk[1];
var div = {Value: divs[x]}; //x value comes from timedreveal div
var divtoreveal = document.getElementById(div);
divtoreveal.style.visibility = 'visible';
}
function timedreveal() {
var textchunk = "invite" //the textchunk value will later be set by another function but
//here I just set it to invite so I could try to get it working
var times = textchunk[0];
for(var x = 0; x < times.length; x++)
{
var wait = {Value: times[x]};
alert(JSON.stringify(wait, null, 4));
setTimeout(reveal, wait);
}
}
timedreveal retrieves 'itimes' just fine from the 'invite' array but then when I alert its length I get the length of the word 'itimes' and not the length of the 'itimes' array. The first value it retrieves is "i" not "0". It is not treating 'itimes' as the name of the array but as as the values of an array named 'times' with 6 elements. I have tried to look this up and read a bunch of posts but haven't understood how to fix it. One suggested I put all three arrays inside a sort of superarray but I don't understand how to access the data in that case. Any advice would be great.
Thanks, Kate
var itimes =["0", "642", "950", "2555", "1113"]; //times in msec when text should be revealed
var idivs = ["speech_bubble", "i1", "i2", "i3", "i4"]; //divs to be revealed
var invite =[itimes,idivs];
var times = invite[0]; // in timedreveal()
var divs = invite[1]; // in reveal()
can you try like this, because you're pushing strings in array not array themselves.
You are assigning a string instead of array.
var textchunk = "invite"
should be
var textchunk = invite;
In your case
> var textchunk = "invite"
> var divs = textchunk[1];
textchunk will a string "invite" and techchunk[1] will return the letter at position 1, so divs will have value n

Run through for loop and randomly change values of variable within a range but satisfy all variables

So what I have is a quiz which is generated dynamically. I want the quiz questions to be ordered randomly. Basically, the i is going from 0 to the length of answerArray. I want it to do this, but not in order randomly. For instance: instead of 0,1,2,3,4,5 I want 1,0,2,3,5,4. I have tried doing this but all of my attempts failed. It would be very helpful if I could do this so the test questions would not always be in order. Thank you.
var displayAnswers = function (){
for (var i = 0; i<answerArray.length;i++){
var row1= document.createElement("div");
$(row1).addClass("row");
var colmd= document.createElement("div");
$(colmd).addClass("row");
$(colmd).addClass("text-center");
$(colmd).addClass("rowtxt");
$(colmd).attr('id',"questionTxt"+[i+1]);
$("#contain").append(row1)
$(row1).append(colmd);
var answer = answerArray[i];
}
You can use accepted answer in the following question Generate unique random numbers between 1 and 100, that will generate the random numbers first and store them in array and use them inside for loop.
Example :
var arr = [];
var answerArray = ["Answer 1", "Answer 2", "Answer 3"];
while( arr.length < answerArray.length ){
var randomnumber=Math.ceil( Math.random() * answerArray.length)
var found=false;
for(var i=0;i<arr.length;i++){
if(arr[i]==randomnumber){found=true;break}
}
if(!found)arr[arr.length]=randomnumber;
}
Now you have an array of unique numbers between 0 and answerArray length, you can use it inside the loop just by calling arr[i] :
var displayAnswers = function (){
for (var i = 0; i<answerArray.length;i++){
var row1= document.createElement("div");
$(row1).addClass("row");
var colmd= document.createElement("div");
$(colmd).addClass("row");
$(colmd).addClass("text-center");
$(colmd).addClass("rowtxt");
$(colmd).attr('id',"questionTxt"+[i+1]);
$("#contain").append(row1)
$(row1).append(colmd);
//Here you get the unique number between 0 and answers length
var random_number = arr[i];
var answer = answerArray[random_number];
}
}
Hope this helps.
I would start by thinking about what you need to do.
You want to track what numbers you have used already and getting a new number if you have already used the one generated.
Try something like this.
// The initial array
var Array = [1,2,3,4,5];
// The new array or tracking array
var Used = [];
// A function to generate the random index
// We need a function so we can call it if
// the index already exists to ensure we have
// the same amount of values as the inital
// array
function addRandomNum(array) {
var random = Math.floor((Math.random() * Array.length) + 1);
if(array.indexOf(random) === -1){
array.push(random);
} else {
addRandomNum(array);
}
};
// Loop the inital array calling the function
for(var i = 0; i < Array.length; i++){
addRandomNum(Used);
}
// Look at the new randomized array
console.log(Used);
You could shuffle the array, if that is what you want.
There are shuffle functions if you follow this link of css-tricks:
https://css-tricks.com/snippets/javascript/shuffle-array/
I like technique 2. Which uses the sort function to randomly create a negative or positive number which will sort the items according to the returned value.
If the returned value is positive, the first item will precede the second that is passed to the function. As you can see, the parameters are unused because we don't want a logic sort but a randomized based on a random number.
You could call it like this:
answerArray.sort(function(item1, item2) { return 0.5 - Math.random() });
Ok, I will assume a few things. Your answerArray looks like this:
var answerArray = [
{
"q_id": "1",
"prompt": "Is StackOverflow awesome?",
"a1": "Yes",
"a2": "No",
"correct": "a1"
}
];
First add a property like this
"random": Math.floor(Math.random() * 101)
This will create a random number that you can use to sort the array, like so:
answerArray.sort(function(a, b) {
return parseFloat(a.random) - parseFloat(b.random);
});
This way you can sort the questions randomly.

How to randomly select numbers within an arbitrary range and add together using JavaScript arrays

I am trying to write some JavaScript that will select some random numbers from an array and then add those selected numbers to make a single total value.
For example if i had var array = [1, 22, 5, 88, 3, 105, 7, 88, 987] i would then like the code to select however many numbers it wants at random(amount selected changes every time it runs) and then add them together but i am not sure if this is even possible.
I am new to JavaScript so i have only managed to write code that adds all the array elements together instead of selecting at random.
var arr = [1,2,3,4,5,6];
var total=0;
for(var i in arr) { total += arr[i]; }
My code is very basic so please excuse me for this i'm still learning. Thank You
You could use the Math.rand() function in order to create a random index. In terms of code:
// The array with your elements
var arr = [1,2,3,4,5,6];
// An array that will keep track of the elements we have selected.
var selectedIndex = [];
// The sum.
var sum=0;
// times is the number of elements we want to select from arr and sum them.
for(var i=0; i<times; i++)
{
// Get a random integer number in the range [0, arr.length]
var index = Math.floor(Math.rand()*arr.length);
// check if the index we created has been selected again.
if(selectedIndex.indexOf(index)>-1)
{
// The created index has been selected again. So we must select another one,
// in order we get an item from the array only once.
while(selectedIndex.indexOf(index)>-1)
index = Math.floor(Math.rand()*arr.length);
}
// We push the created index in the selected index array.
selectedIndex.push(index);
// We increase the sum.
sum+=arr[index];
}
update
In order the above to be executed the caller should provide a value for the variable called times. This value in order to be valid shouldn't exceed the length of the array called arr.
Another way more elegant, it would be to follow on this part the solution that deitch suggested in his post.
var times = Math.floor((Math.random() * arr.length)+1)
The above should be placed just before the for statement.
I think you are looking something like:
<code>
function randormTotal() {
var arr = [1,2,3,4,5,6];
var total=0;
var noOfData = 3;
for(var i =0; i<noOfData; i++) {
var pos = Math.floor(Math.random()*(arr.length-1)) + 1;
total += arr[pos];
}
alert(total);
}
</code>
FYI, this method actually modifies the array, so you might want to copy it.
// randomly select how many elements you will pick
var i, total = 0, elmsCount = Math.floor((Math.random() * arr.length)+1), current;
// select that many elements
for (i=0; i<elmsCount; i++) {
current = Math.floor(Math.random()*arr.length);
total += arr.splice(current,1)[0];
}
// total is now the sum

String to arrays

I have below String that needs to be divided into multiple array after 5 comma separated values. Then I need to put each array values to textbox values using script. I tried the below code to split and assign to array but not working. Is there any way this can be resolved? <%=ab%> is the JavaScript variable that contains the below code.
[768.234.232, 768.234.232, 574,10-10-2012, 10-10-2012, 768.234.232, 768.234.232, 987, 10-10-2012, 10-10-2012]
function functionOne() {
var list = "<%=ab%>";
var ab = new Array();
var i = 0;
for (i = 0; i < 10; i++) {
ab[i] = list.split(",", 3);
alert(ab[i]);
}
}
"needs to be divided into multiple array after 5 comma seperated values"
You seem to be saying that the result should be one array with five values in it and then a second array with the next five values in it, etc. If so, you can do the following:
var list = "<%=ab%>";
list = list.slice(1,-1); // remove the enclosing []
var allValues = list.split(/\s*,\s*/); // split on comma with optional whitespace
var a = [];
for (var i = 0; i < allValues.length; i+=5) {
a.push( allValues.slice(i, i+5<=allValues.length ? i+5 : allValues.length) );
}
After running the above, a will be array that contains other arrays. a[0] is an array of the first five items, so, e.g., a[0][2] is the third item. a[1] is an array of the next five items. If there were more than ten items in the original list then a[2] would be an array of the next five, etc. If the total number of items is not divisible by five then the last array would hold the remainder.
Demo: http://jsfiddle.net/9xAxz/
"Then I need to put each array values to textbox values"
Um... does that mean one item per textbox? If so, why did you want to divide up after five values? Do you mean five items per textbox? Either way are you talking about dynamically creating textboxes? If so you can follow the above code with something like this:
var tb;
for (i = 0; i < a.length; i++) {
tb = document.createElement('input');
tb.value = a[i].join(", ");
document.body.appendChild(tb);
}
Demo: http://jsfiddle.net/9xAxz/1/
If I'm completely off base on any of the above, well... think about editing your question to make it clearer. I suppose I should've clarified before answering, but please update the question to show what your desired output is for that input.
function functionOne() {
var list = "<%=ab%>".split(/,\s?/g);
for (var i = 0; i < list.length; i++) {
t = document.createElement('input');
t.type = 'text';
t.value = list[i];
document.body.appendChild(t);
}
}
functionOne();
http://jsfiddle.net/WJPHt/1/

jquery get the unreapeatable values

i have a array with numbers. i need that array value to be generated once i click on the button, while i click on the button i need to get the value random wise from the array, but the value should not be repeated.
ex, if i get a 2 from out of 5, then i should not get the 2 again. for this i wrote this function, but the values are repeating... any idea?
var ar = [0,1,2,3,4,5];
var ran = Math.floor(Math.random()*ar.length);
ar.splice(ran,1);
alert(ar.splice);
the array values should not be removed. because if i click the button again, i need to get the values like before.
i did my work like this : but the rand values are repeating, any one can correct this to get unrepeatable values to get?
$(document).ready(function(){
var myArray = [1,2,3,4,5];
var mySize = 5;
x = 0;
while(mySize>=1){
var rand = Math.floor(Math.random()*mySize);
mySize--;
alert(rand);
}
})
You need your array to be in an outer scope for this like:
(function(){
var ar = [0,1,2,3,4,5];
document.getElementById('thebutton').onclick = function(){
alert(ar.splice(Math.floor(Math.random()*ar.length), 1));
};
})();
JSFiddle Example
If you create your array inside the onclick function then you are just recreating the entire array every time the button is clicked.
Take a look at this demo. In this it randomizes the array values and will repeat only after all the values are utilized.
Demo
Based on the update in your question here it is take a look.
http://jsfiddle.net/MbkwK/2/
var ar = [0, 1, 2, 3, 4, 5];
document.getElementById('thebutton').onclick = function() {
var shuffle = [];
var copyarr = ar.slice(0);
var arlength = copyarr.length;
for (i = 0; i < arlength; i++) {
shuffle.push(copyarr.splice(Math.floor(Math.random() * copyarr.length), 1));
}
alert(shuffle.join(","));
};
Working demo - http://jsfiddle.net/ipr101/qLSud/1/

Categories

Resources