Search code examples
javascriptarraysecmascript-6

do not understand how array destructuring works here


I am trying to implement a very simple cyclic sort in JS, and I am having issues with the swapping functionality of the algorithm.

const sort = (nums) => {
    for (let i = 0; i < nums.length; i++) {
        while (nums[i] != i) {
            [nums[i], nums[nums[i]]] = [nums[nums[i]],nums[i]];
        }
    }
    return nums;
};

Here is my input:

sort([1, 4, 3, 2, 5, 7, 6, 0])

On the first iteration of the for and while loops, I get the following error:

            [nums[i], nums[nums[i]]] = [nums[nums[i]],nums[i]];
                                     ^

TypeError: Cannot set properties of undefined (setting '4')

In my node console, I tried a similar method, just without the dynamic index, and it worked.

> const arr = [ 1, 2, 3, 4, 5 ]
> [arr[0], arr[arr[2]]] = [arr[arr[2]], arr[0]]
[ 4, 1 ]
> arr
[ 4, 2, 3, 1, 5 ]

Looking at the ECMA script specification, at the IteratorDestructuringAssignmentEvaluation, I cannot figure out how JS is doing this destructuring, and why my method isn't working.

Thank you in advance!


Solution

  • The problem occurs in your destructuring assignment:

    [nums[i], nums[nums[i]]] =  ...
    

    The order of assignment is that first nums[i] is assigned, and then the next array index is assigned. But there is the problem that next index (which is nums[i]) was just updated! So that second assignment is going to the wrong index.

    You can solve this with a temporary variable:

    let j = nums[i];
    [nums[i], nums[j]] = [nums[j],nums[i]];