I encountered some strange destructuring behavior when reversing a linked list in this problem:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let previous = null
while (head) {
// Version 1 - works
[head.next, head, previous] = [previous, head.next, head]
// Version 2 - doesn't work
// [previous, head, head.next] = [head, head.next, previous]
// Version 3 - doesn't work
// [head, head.next, previous] = [head.next, previous, head]
}
return previous
};
I cannot for the life of me figure out why destructing assignments v2 and v3 don’t work while version 1 does. The head.next
assignment is causing the problem. The error is:
Line 16 in solution.js
[previous, head, head.next] = [head, head.next, previous]
^
TypeError: Cannot set properties of null (setting 'next')
Can someone explain way version 1 works and versions 2 and 3 do not?
2
Answers
It’s easier to see the difference if you break up the destructuring into separate assignments.
Version 1 is equivalent to:
Version 2 is equivalent to:
And version 3:
In versions 2 and 3 you’re assigning
head.next
after you’ve reassignedhead = head.next
. But you need to change thenext
property of the originalhead
node, not the new one.And if the original
head.next
wasnull
, you’ll get an error when you try to assignhead.next
after the assignment, because you can’t set properties ofnull
.JavaScript is destructuring the array one by one. Version 2 gives you an error because JavaScript does this:
Hence why only the first solution works.