I am writing a couple of javascript functions to help randomly select articles from a JSON feed.
I have created a function called getRandomNumberFromRange which takes 2 parameters: the minimum and maximum numbers of a range of numbers to select from. The number of articles to be selected at random is provided via a data attribute on the DOM element which will eventually be populated with the articles.
The second function loadStories loops through the amount of articles which needs to be retrieved and calls the getRandomNumberFromRange function to get a number. This number will eventually be used as a key to select articles from the JSON feed array.
To ensure that a random number is not picked more than once, I have created an array to store previously picked numbers, which I will check against when the number is picked. If the number is in the array already, another number is picked, if it isn't it is added to the array.
This Codepen shows what I have so far. The code is also shown below:
var setupEmployeeStories = function () {
var
$element = $(".related-employee-stories"),
noOfStories = parseInt($element.attr("data-stories")),
arrSelectedNumbers = [],
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
getRandomNumberFromRange(min, max);
}
return randomNumber;
},
loadStories = function(){
for(var i = 0; i < noOfStories; i++){
var rand = getRandomNumberFromRange(0, 4);
console.log(rand);
}
console.log(arrSelectedNumbers);
};
loadStories();
};
setupEmployeeStories();
Unfortunately I'm getting some odd results from the functions when the functions select the same random number multiple times. For some reason getRandomNumberFromRange tends to return a completely different number than what was actually picked by the function. This can be seen by the differences in the (console) logged results and the final array - arrSelectedNumbers
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
randomNumber = getRandomNumberFromRange(min, max);
}
return randomNumber;
}
You need to set getRandomNumberFromRange to randomNumber to get the result of the recursive function.
var setupEmployeeStories = function () {
var
$element = $(".related-employee-stories"),
noOfStories = parseInt($element.attr("data-stories")),
arrSelectedNumbers = [],
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
randomNumber = getRandomNumberFromRange(min, max);
}
return randomNumber;
},
loadStories = function(){
for(var i = 0; i < noOfStories; i++){
var rand = getRandomNumberFromRange(0, 4);
//console.log(rand);
}
console.log(arrSelectedNumbers);
};
loadStories();
};
setupEmployeeStories();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="related-employee-stories" data-stories="3"></div>
Related
I need to generate the unique numbers, join it with the letter and push to array.
arr = []
for (var i = 0; i < 5; i++) {
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var randomNum = generateRandomNumber(1, 15);
if (!arr.includes(randomNum)) {
arr.push('B' + randomNum.toString())
} else {
if (arr.length < 5) {
return generateRandomNumber(min, max)
} else break
}
}
I have provisioned uniqueness check, however the same values are still coming.
Condition only checked once in the loop.
Also if the condition is in the else state, there is a chance that there will also be same number as previous.
You can use this approach
let arr = []
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function add(){
var randomNum = generateRandomNumber(1, 15);
if(arr.length < 5){
if (!arr.includes('B' + randomNum.toString())) {
arr.push('B' + randomNum.toString())
}
add()
}
}
add()
console.log(arr)
I have provisioned uniqueness check, however the same values are still coming.
The uniqueness check is incorrect.
The array contains only strings starting with letter 'B' (added by the line arr.push('B' + randomNum.toString())) while the uniqueness check searches for numbers.
The call arr.includes(randomNum) always returns false. Each and every generated value of randomNum is prefixed with 'B' and pushed into the array, no matter what the array contains.
Try a simpler approach: generate numbers, add them to the list if they are not already there, stop when the list is large enough (five items).
Then run through the list and add the 'B' prefix to each item.
Like this:
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// Generate 5 unique random numbers between 1 and 15
let arr = []
while (arr.length < 5) {
let num = generateRandomNumber(1, 15);
// Ignore a value that has already been generated
if (!arr.includes(num)) {
arr.push(num);
}
}
// Add the 'B' prefix to the generated numbers
arr = arr.map((num) => `B${num}`);
console.log(arr);
I have the following script, which is meant to generate 2 different numbers
<script type="text/javascript">
function GenerateRandomNumber2to6No1() {
var min = 2, max = 7;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
var GenerateRandomNumber2to6No1 = GenerateRandomNumber2to6No1();
$('.GenerateRandomNumber2to6No1').html(GenerateRandomNumber2to6No1);
function GenerateRandomNumber2to6No2() {
var min = 2, max = 7;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber2to6No1) ? random: GenerateRandomNumber2to6No2();
}
var GenerateRandomNumber2to6No2 = GenerateRandomNumber2to6No2();
$('.GenerateRandomNumber2to6No2').html(GenerateRandomNumber2to6No2);
</script>
NUMBER 1: <span class = "GenerateRandomNumber2to6No1"></span>
NUMBER 2: <span class = "GenerateRandomNumber2to6No2"></span>
This usually works fine but occasionally the page will load and no numbers will appear. I'm guessing this is when GenerateRandomNumber2to6No2 happens to generate the same number as GenerateRandomNumber2to6No1. I thought that
return (random !== GenerateRandomNumber2to6No1) ? random: GenerateRandomNumber2to6No2(); accounted for this, but perhaps instead of generating another unique number when there's redundancy, it generates no number at all. Is this the case? If so, how can I fix this?
Thanks!
function getRand(){
var array=[2,3,4,5,6,7]
var newArray=[];
for(var i=0;i<2;i++){
var ran=~~(array.length*Math.random());
newArray[i]=array.splice(ran,1)[0]
}
return newArray
}
var ranArray=getRand();
var ran1=ranArray[0];
var ran2=ranArray[1];
console.log(ran1,ran2)
getRand() is a function to give you an array of distinct numbers.Since you only need two,it only loop two times,and give you an array,which you can make use of it.
Back to your code,from what I see,Gno2 should keep running until it got another number,I don't know why.It's the time you try to debug.
First I will try to change the max=2 to max=3,if the code may not work for some number,then you can quickly realize and found out the problem is in these two functions.
Then try to log,console.log(Gno1,Gno2),see what exactly the numbers are,also help you to know where is the problem.
I think this piece of code can help you
var rand1,rand2;
var min = 3;
var max = 6;
do {
rand1 = Math.floor(Math.random() * (max - min)) + min;
rand2 = Math.floor(Math.random() * (max - min)) + min;
}while(rand1 === rand2);
$('.GenerateRandomNumber2to6No1').html(rand1);
$('.GenerateRandomNumber2to6No2').html(rand2);
I am trying to create a game for fun in Captivate. The game will mimic a wheel of fortune or spin the wheel format.
I am trying to put a different spin on it, and not have any repeating numbers.
Here is what I have so far:
function getRandomInt (min, max) {
var jsRandomNumber = Math.floor (Math.random () * (max - min + 1)) + min;
if(jsRandomNumber==1){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 1);
}else if (jsRandomNumber==2){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 2);
}else if (jsRandomNumber==3){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 3);
}else if (jsRandomNumber==4){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 4);
}else if (jsRandomNumber==5){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 5);
}else if (jsRandomNumber==6){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 6);
}else if (jsRandomNumber==7){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 7);
}else if (jsRandomNumber==8){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 8);
}
}
getRandomInt(1,8);
I don't understand how to prevent repetitive numbers. I also can assign values in Captivate if a slide has been viewed, however I don't understand how to skip that slide if the random number is generated. Any help is greatly appreciated.
You can have an array store what is pending and keep on deleting what has been shown.
function getRandomInt () {
var min = 0; //1st arr element index
var max = arr.length-1; // last arr element index
if(max<0){
return false; //else repopulate the array or based on what you want
}
var randomIndex = Math.floor (Math.random () * (max - min + 1)) + min;
var randomNumber = arr.splice(randomIndex,1)[0];
//extract the item in that randomIndex position,
//since the array is global it will affect the array next time,
//we will not have that value in the next call.
//window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', randomNumber);
console.log(randomNumber);
}
//generate a random array to keep track
var arr = function(){
var min = 1, max = 8, atr = [];
for(var i=min; i<=max; i++){
atr.push(i);
}
return atr;
}();
//run a few times to test.
getRandomInt();
getRandomInt();
getRandomInt();
getRandomInt();
getRandomInt();
I am generating a list of random numbers. Each random number is added to an array, but I want to check that the same number isnt entered twice. I am having a lot of trouble trying to get the if statement to work with this and am not sure what I have done wrong.
I have created:
//INITIALISE VARS, ARRAYS
var uniquearr = [];
i = 0;
while (i < 30){
var min = 0;
var max = 29;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
//SEARCH UNIQUE ARRAY FOR EXISTING
if (jQuery.inArray(random, uniquearr) > -1){
//ADD NUMBER TO UNIQUE ARRAY
uniquearr.push(random);
//*DO SOMETHING*
} //END IF
i++;
} //END WHILE
But the if statement never triggers. Can anyone point me in the right direction?
You need to test whether the random number does not exist in the array; only then should it be added to the array.
Also another problem with the logic was, you were not adding the 30 unique numbers always as the i variable was incremented outside the if condition. Here you do not have to use a different loop variable since you can check whether the destination array is of desired size
//INITIALISE VARS, ARRAYS
var uniquearr = [], min = 0, max = 29;
//SEARCH UNIQUE ARRAY FOR EXISTING
while (uniquearr.length < 30){
var random = Math.floor(Math.random() * (max - min + 1)) + min;
if (jQuery.inArray(random, uniquearr) == -1){
uniquearr.push(random);
}//END IF
}//END WHILE
console.log('uniquearr', uniquearr)
That's because your if statement always is false, your array is empty and as result $.inArray always returns -1, you should check whether the returned value is -1 or not.
while (uniquearr.length < 30) { // uniquearr.length !== 30
var min = 0,
max = 29,
random = Math.floor(Math.random() * (max - min + 1)) + min;
//SEARCH UNIQUE ARRAY FOR EXISTENCE
if (jQuery.inArray(random, uniquearr) === -1) {
//ADD NUMBER TO UNIQUE ARRAY
uniquearr.push(random);
}
}
http://jsfiddle.net/zzL7v/
I'm trying to create a javascript function that accepts 2 parameters min and max and generates a random number between the two integers. That part is easy.
Where things get rough is that I need to create a conditional that says
function generateNum (min, max) {
var randNumber = Math.ceil(Math.random()*(max - min)+min);
if (randNumber === max) {
// store the result (probably in an array) and generate a new
// number with the same behavior as randNumber (e.g. it is also
// stores it's total in the array and recursively "re-generates
// a new number until max is not hit)
}
}
The idea is to recursive-ise this so that a running total of the number of max hits is stored, combined, and then returned.
For example: The script receives min / max parameters of 5/10 generateNum(5,10){}. If the value generated by randNumber were 5, 6, 7, 8, or 9 then there would be no recursion and the function would return that value. If the value generated by randNumber is 10, then the value 10 is stored in an array and the function now "re-tries" recursively (meaning that as many times as 10 is generated, then that value is stored as an additional object in the array and the function re-tries). When the process stops (which could be infinite but has a parabolically decreasing probability of repeating with each recursion). The final number (5, 6, 7, 8, 9) would be added to the total of generated max values and the result would be returned.
Quite an unusual mathematic scenario, let me know how I can clarify if that doesn't make sense.
That part is easy.
Not as easy as you think... The algorithm that you have is broken; it will almost never give you the minimum value. Use the Math.floor method instead, and add one to the range:
var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;
To do this recursively is simple, just call the method from itself:
function generateNum (min, max) {
var randNumber = Math.floor(Math.random()*(max - min + 1)) + min;
if (randNumber == max) {
randNumber += generateNum(min, max);
}
return randNumber;
}
You can also solve this without recursion:
function generateNum (min, max) {
var randNumber = 0;
do {
var num = Math.floor(Math.random()*(max - min + 1)) + min;
randNumber += num;
} while (num == max);
return randNumber;
}
There is no need to use an array in either case, as you don't need the seprate values in the end, you only need the sum of the values.
I assume that you don't really need a recursive solution since you tagged this for-loop. This will return the number of times the max number was picked:
function generateNum (min, max) {
var diff = max - min;
if(diff <= 0)
return;
for(var i = 0; diff == Math.floor(Math.random()*(diff + 1)); i++);
return i;
}
Example outputs:
generateNum(1,2) // 3
generateNum(1,2) // 1
generateNum(1,2) // 0
generateNum(5,10) // 0
generateNum(5,10) // 1
Two things:
1) the probability to roll 10 stays (theoretically the same on each roll (re-try)), the low probability is of hitting n times 10 in a row
2) I don't see why recursion is needed, what about a while loop?
var randNumber;
var arr = [];
while ((randNumber = Math.ceil(Math.random()*(max - min)+min)) === max) {
arr.push(
}
I'd consider an idea that you don't need to use not only recursion and arrays but not even a for loop.
I think you need a simple expression like this one (separated into three for clarity):
function generateNum (min, max)
{
var randTail = Math.floor(Math.random()*(max - min)+min);
var randRepeatMax = Math.floor(Math.log(Math.random()) / Math.log(1/(max-min+1)));
return randRepeatMax*max + randTail;
}
Assuming one random number is as good as another, this should give you the same distribution of values as the straightforward loop.
Recursive method:
function generateNum (min, max) {
var res = Math.floor(Math.random() * (max - min + 1)) + min;
return (res === max) ? [res].concat(generateNum(min, max)) : res;
}