Search code examples
javascriptecmascript-6destructuring

Swapping array values with destructuring assignment and indexOf()


I'm trying to swap the two lowest values in a shuffled array containing the numbers 0-14. For those curious, I'm implementing the shuffling algorithm for a 15 puzzle described by pkpnd here.

I wanted to try destructuring assignment, as described here, but am encountering an unexpected behavior. I realize that I can get my code working (and make it more readable) by just creating a temporary variable, but I'd like to understand what's happening before moving on.

I'm grabbing a subset of my array [1,2] and then trying to replace it with [2,1]. For some reason, it's only swapping the values when their order in the original array is opposite of the order of my subset.

I originally tried this:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 3, 4];
[arr1[arr1.indexOf(1)], arr1[arr1.indexOf(2)]] = [arr1[arr1.indexOf(2)], arr1[arr1.indexOf(1)]];
[arr2[arr2.indexOf(1)], arr2[arr2.indexOf(2)]] = [arr2[arr2.indexOf(2)], arr2[arr2.indexOf(1)]];
console.log("arr1: " + arr1, "\narr2: " + arr2);

And then tried this:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 3, 4];
[arr1[arr1.indexOf(1)], arr1[arr1.indexOf(2)]] = [2, 1];
[arr2[arr2.indexOf(1)], arr2[arr2.indexOf(2)]] = [2, 1];
console.log("arr1: " + arr1, "\narr2: " + arr2);

But both produce identical output:

arr1: 1,2,3,4 
arr2: 1,2,3,4

I would expect that the position of 1 and 2 would be swapped for both arrays, but they're only swapped in arr2. I suspect this has to do with they way the initial array subset [1,2] is created, but I'm not sure.

Can anybody explain why the values aren't always swapped?


Solution

  • The result is simple, because it goes step for step for each item of destructuring assingment. And while the values are changing, the index of the values changes.

    Case 1 [1, 2, 3, 4]

    1. Get index of target for the first value 2

      [arr1[arr1.indexOf(1)], arr1[arr1.indexOf(2)]] = [2, 1];
      //    ^^^^^^^^^^^^^^^                                     0
      
    2. Assign 2 to arr1[0]

      [2, 2, 3, 4]
      
    3. Get index of target for the second value 1:

      [arr1[arr1.indexOf(1)], arr1[arr1.indexOf(2)]] = [2, 1];
      //                           ^^^^^^^^^^^^^^^              0
      
    4. Assign 1 to arr1[0]

      [1, 2, 3, 4]
      

    Case 2 [2, 1, 3, 4]

    1. Get index of target for the first value 2

      [arr2[arr2.indexOf(1)], arr2[arr2.indexOf(2)]] = [2, 1];
      //    ^^^^^^^^^^^^^^^                                     1
      
    2. Assign 2 to arr1[1]

      [2, 2, 3, 4]
      
    3. Get index of target for the second value 1:

      [arr2[arr2.indexOf(1)], arr2[arr2.indexOf(2)]] = [2, 1];
      //                           ^^^^^^^^^^^^^^^              0
      
    4. Assign 1 to arr1[0]

      [1, 2, 3, 4]