2

People

My question is the following. I have two arrays, and I would like to move an element from array A to array B. However it is not so easy. Which element would go is totally random based. I copy my code so my goal would be easier to understand:

var array1 = ["A","B","C"];
var array2 = [];
var move = function() {
var x = Math.floor((Math.random() * 100) + 1);
 if (x > 0 && x < 33.1 && array1[0] !== "undefined")
        {array2.push(array1[0])
         delete array1[0]
         }
  if (x > 33.2 && x < 66.1 && array1[1] !== "undefined")
        {array2.push(array1[1])
         delete array1[1]
         }
  if (x > 66.2 && x < 100.1 && array1[2] !== "undefined")
        {array2.push(array1[2])
         delete array1[2]
         }
  else {
  move();
  return
  }
}
move();
move();
move();
console.log(array1);
console.log(array2);

So the objective is that the function called 3 Times, we would have the three elements in the B array. I would like my function to restart automatically if the random number is "undefined". So for the next random roll, it would pick another element. And so on so on. My idea in the code, but its not working, since it is still dropping "undefined" ones. Thanks,

Koppany
  • 57
  • 9
  • array1[2] !== "undefined" You are comparing not to undefined, but to a string with text of 'undefined' ;) what you want is array1[2] !== undefined – grzesiekgs Dec 02 '16 at 11:31
  • You should use `typeof array1[2] !== "undefined"` – VDarricau Dec 02 '16 at 11:32
  • 1
    Second thing. I don't know what do You mean by saying : 'I would like my function to restart automatically if the random number is "undefined"' Math.random will always return number between 0 and 1 – grzesiekgs Dec 02 '16 at 11:33
  • Possible duplicate of [Deleting array elements in JavaScript - delete vs splice](http://stackoverflow.com/questions/500606/deleting-array-elements-in-javascript-delete-vs-splice) – CBroe Dec 02 '16 at 11:34
  • And the 3rd thing. Do not delete items from array! Splice the array instead. Array in JS is actually an object, thats why Your code is valid, but it basically breaks Your array, because after such deletion, Your array is not continous (it doesn't have indexes like : 0, 1, 2, 3 but for example : 0, 3, 5) – grzesiekgs Dec 02 '16 at 11:35
  • But really you could sidestep this whole issue by keeping the array such that all the n elements still there are in spots zero to n-1, and picking index given by floor of random times n – Jeremy Kahan Dec 02 '16 at 11:38
  • Really you may be after http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array. – Jeremy Kahan Dec 02 '16 at 12:32
  • Thanks. Maybe I wasnt enough clear. So according to var X, it would either pick "A" or "B" or "C" from the array, and put it to array2. So when second time I call the function, it would pick "A" or "B" or "C" or "undefined". The main goal is to restart the function if it would put "undefined", and let it go over again and again, till it hits an element with number. – Koppany Dec 02 '16 at 14:28

3 Answers3

1

Why not use Array#splice with a random value which reflects the length of array1.

var array1 = ["A", "B", "C"],
    array2 = [],
    move = function () {
        var x = Math.floor((Math.random() * array1.length));
        array2.push(array1.splice(x, 1)[0]);
    };

move();
move();
move();
console.log(array1);
console.log(array2);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • yes. splice is working that way, if the second parameter is not equal 0. the result is an array, which i use only the one item, i have spliced. – Nina Scholz Dec 02 '16 at 11:48
  • 1
    Thanks. Confused splice and slice. – Jeremy Kahan Dec 02 '16 at 11:50
  • I am wondering if this would be better (clearer? More generalizable for sure) if you put a single move command inside a for loop and perhaps made three a constant or a variable set to three or to the length of the original array (before the loop). Or even a while the array length of array 1 is positive loop? – Jeremy Kahan Dec 02 '16 at 12:02
  • @JeremyKahan, please ask the op, why such style is necessary. for me, it looks like take a random value out of `array1` and push it to `array2` for one call. the recursive style is just for moving at least one item. but this is made very complicates with factors for random and adding 1. then the selection is strange, because check for negative values or check for values which have a gap, like `< 33.1` and `> 33.2` are mysteriously. – Nina Scholz Dec 02 '16 at 12:07
  • Exactly. When I read it I felt the same. But percents are more intuitive for some people. What I was getting at though is move move move feels like it should be while(array1.length) move. – Jeremy Kahan Dec 02 '16 at 12:11
0

When you test for, e.g., array1[1] !== "undefined" you are not testing if the variable is undefined, but if the variable is equal to a string whose value is "undefined".

Thus, you could replace "undefined" by undefined, e.g. replace

yourVar !== "undefined"

by

yourVar !== undefined

Even if i do not recommand to do this by any mean, since it will work only so long as someone doesn't create a variable named undefined. Also, given that you are testing for the existence of your variable, as other say, the correct way to do your test is via doing

typeof yourVar !== 'undefined'

For more details, see How to check a not-defined variable in JavaScript

UPDATE Then to prevent your function from entering an infinite loop, you should check if your array only contains null elements.

First you should define a function which can check for this, as follows

Array.prototype.isNull = function (){
    return this.join().replace(/,/g,'').length === 0;
};

And then you should condition the recursive call of move() by the non-nullity of array1. Via replacing

else {move();return}   

by

else {if (!array1.isNull()){move()};return}
Community
  • 1
  • 1
keepAlive
  • 6,369
  • 5
  • 24
  • 39
  • Hi, I liked your explanation, very simple and easy to grasp. However, I constantly getting the same error message: VM113:4 Uncaught RangeError: Maximum call stack size exceeded – Koppany Dec 02 '16 at 14:08
  • @Koppany. It seems that your function is likely to enter an infinite loop from the second call of move function. Which causes “Maximum call stack size exceeded”. Actually array1 is likely to be composed of null values when `move` function is called the second time. You must condition the recursive call as shown above in my updated answer. – keepAlive Dec 02 '16 at 23:50
0

Your condition array1[x] !== "undefined" is wrong. It will check array1[x] for the string "undefined"

You need to use something like

typeof(array1[x]) !== 'undefined'
Amoolya S Kumar
  • 1,458
  • 9
  • 10