1

I want to shuffle an array in javascript...

I first wrote this function:

function shuffle(arr) {
    for (i = 0; i < arr.length; i++) {
        let temp0 = arr[Math.floor(Math.random() * arr.length)];
        let temp1 = arr[Math.floor(Math.random() * arr.length)];
        console.log(temp0); // select random item work correctly
        console.log(temp1); // select random item work correctly
        if (temp0 === temp1) { //for dont change arr[index] with save value!!!
            continue;
        }
        temp2 = temp0;
        temp0 = temp1;
        temp1 = temp2;
        console.log(temp0); //all temp0, temp1, temp2 are equal!!!
        console.log(temp1); //all temp0, temp1, temp2 are equal!!!
        console.log(temp2); //all temp0, temp1, temp2 are equal!!!
    }
    return arr
}

My algorithm is as follow:

  • select an item randomly
  • select another item randomly
  • switch the two items together

But I end up with temp0, temp1 and temp2 all equal!!!

Then I changed my code to this and it works perfectly

function shuffle1(arr) {
    for (i = 0; i < arr.length; i++) {
        x = Math.floor(Math.random() * arr.length);
        y = Math.floor(Math.random() * arr.length);
        if (x === y) { //for dont change arr[index] with self !!!
            continue;
        }
        temp0 = arr[x];
        arr[x] = arr[y];
        arr[y] = temp0;
    }
    return arr
}

The only change that has happened is that: the randomly created number for index,is assigned to a variable and then this variable is used for selecting an item in array.

Can anyone help me understand why the first example does not work as expected in the second example?

Thanks in advance

j3ff
  • 5,719
  • 8
  • 38
  • 51
sMohammad14
  • 33
  • 1
  • 6
  • Does this answer your question? [How can I shuffle an array?](https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array) –  Mar 12 '20 at 22:56
  • you have a typo in `shuffle()` at `tmep0 = temp1;` and javascript refers to a variable from outer (global) scope – Yone Mar 12 '20 at 23:05
  • Checkout https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array – haron68 Mar 12 '20 at 23:18

2 Answers2

1

Using the Fisher Method should work more efficiently:

/**
 * Shuffles array in place.
 * @param {Array} a items An array containing the items.
 */
function shuffle (arr) {
    var j, x, index;
    for (index = arr.length - 1; index > 0; index--) {
        j = Math.floor(Math.random() * (index + 1));
        x = arr[index];
        arr[index] = arr[j];
        arr[j] = x;
    }
    return arr;
}

Original Answer: https://stackoverflow.com/a/6274381/11937654

Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
Kavelin
  • 397
  • 1
  • 11
0

The reason it does not update is because the numbers you are updating do not refer back to the elements in the array. Lets have a look in the node REPL.

We will create an array and try to update it both ways and see if the update was seen in the array.

> let a = [1,2,3]
undefined
> let f = a[0]  // grab reference to 1st element
undefined
> f
1
> f = 2         // 1. try to update via our variable
2
> a[0]          
1               // update has NOT worked
> a[0] = 2      // 2. try to update by array index
2
> a[0]          
2               // update has worked

Once we change the first function to update via array indices both functions are the same.

When I update f I assign a new number object to it and break the link with a[0] which still refers to the old number. In js numbers are immutable so we cant update them even if we want to.

related: Is number in JavaScript immutable?

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61