1

I need to get random numbers but can't use the same number more than once. I wrote the following functions to create a random number and to check if it has not been used yet.

function randomRecep(){
 return Math.floor((Math.random() * 3));
}

function assignTemp(tempArr){
  console.log("Started assign function, tempArr has: "+tempArr);
  var num = randomRecep();
  for (var i = 0; i < tempArr.length; i++) {
    console.log("num is: " + num + ". check for doubles. tampArr["+i+"] is: "+tempArr[i]);
    if (num == tempArr[i]){
        console.log("FOUND DOUBLE! random num = "+num+" IS ALREADY IN array:"+tempArr)
        assignTemp(tempArr);
        break;
    }
  }    
  tempArr.push(num);
  console.log("pushed " + num + "into array. now is:" + tempArr);
  return num;
}

following is a console output. it seems that the check is working but for some reason at the end of the check instead of just pushing the unique random number and returning its value, it seems that the program pushes also all the previous duplicate numbers and returns the first random number instead of the last one that passed the check. why is that?

Started assign function, tempArr has: -1,2,1
code.js:104 num is: 1. check for doubles. tampArr[0] is: -1
code.js:104 num is: 1. check for doubles. tampArr[1] is: 2
code.js:104 num is: 1. check for doubles. tampArr[2] is: 1
code.js:106 FOUND DOUBLE! random num = 1 IS ALREADY IN array:-1,2,1
code.js:101 Started assign function, tempArr has: -1,2,1
code.js:104 num is: 1. check for doubles. tampArr[0] is: -1
code.js:104 num is: 1. check for doubles. tampArr[1] is: 2
code.js:104 num is: 1. check for doubles. tampArr[2] is: 1
code.js:106 FOUND DOUBLE! random num = 1 IS ALREADY IN array:-1,2,1
code.js:101 Started assign function, tempArr has: -1,2,1
code.js:104 num is: 0. check for doubles. tampArr[0] is: -1
code.js:104 num is: 0. check for doubles. tampArr[1] is: 2
code.js:104 num is: 0. check for doubles. tampArr[2] is: 1
code.js:113 pushed 0into array. now is:-1,2,1,0

this result is good and the idea is that it would stop here. but the process continues on:

code.js:113 pushed 1into array. now is:-1,2,1,0,1
code.js:113 pushed 1into array. now is:-1,2,1,0,1,1

I found code which is much simpler that achieves the above goal. However I am trying to learn and I don't yet understand what went wrong at the end of my method. where is the flaw in the logic?

avielz
  • 35
  • 6
  • Possible duplicate of [Generate unique random numbers between 1 and 100](https://stackoverflow.com/questions/2380019/generate-unique-random-numbers-between-1-and-100) – Herohtar Dec 18 '18 at 22:59
  • You `break`, where you should use `return` instead – Icepickle Dec 18 '18 at 23:00
  • https://stackoverflow.com/questions/18806210/generating-non-repeating-random-numbers-in-js – epascarello Dec 18 '18 at 23:06
  • You're recursively calling the function, so when a loop at some depth finds a missing value, the outer functions have to complete too, so they then push their *num* values into the array. – RobG Dec 18 '18 at 23:09

1 Answers1

1

So the problem with your current code is that you use break, where return should be used here

if (num == tempArr[i]){
    console.log("FOUND DOUBLE! random num = "+num+" IS ALREADY IN array:"+tempArr)
    assignTemp(tempArr);
    break; // <-- should be return instead
}

The reason for this is, that once a non-unique number is found, you restart searching the next numbers, but the break will exit the loop, and directly after the for loop, you add num to your array. So, it would first add a potentially new unique number, and then exit that loop, and return to exit your first loop and then add the non-unique number ;)

You could also rewrite your code in the following way (I do not know if you have any requirements to a certain JavaScript versions, or you are only allowed to use a for loop)

function randomRecep(){
 return Math.floor((Math.random() * 3));
}

function assignTemp(tempArr){
  const number = randomRecep();
  if (tempArr.includes( number ) ) {
    console.warn( `${number} exists in [${tempArr.join(', ')}]` );
    return assignTemp(tempArr);
  }
  console.warn( `adding ${number} to [${tempArr.join(', ')}]` );
  tempArr.push( number );
  return tempArr;
}

const output = [];
// shouldn't call this more than the nr of output possibilities (and the pool here has 3 options)
assignTemp( output );
assignTemp( output );
assignTemp( output );
// we will always expect 0, 1, 2 in the output in some manner
console.log( output );
Icepickle
  • 12,689
  • 3
  • 34
  • 48