When virtual-node children change order, an array diff can describe the change as operations for patching the DOM. A move relocates an existing item; unlike an add, it does not create one. It is one of four operation types: add, remove, move, and noop. section 7.6 section 7.6.1
A move has the shape `{ op: 'move', item, originalIndex, from, index }`. `from` is the item's position when the operation runs, `index` is its destination, and `originalIndex` is its position before diffing began. Keep both positions: earlier removals, additions, or moves may have changed the current index. section 7.6.1 section 7.6
A removal changes the move's starting position
To change `[A, B, C]` into `[C, B, D]`, remove `A` first. `C` started at index 2 but is now at index 1, so its move is `{ op: 'move', item: 'C', originalIndex: 2, from: 1, index: 0 }`. `B` needs no explicit move; record a noop for it, then add `D`. section 7.6.1 section 7.6
To implement the move case in `arraysDiffSequence()`:
- Work on a copy of the old array, alongside an array that tracks each item's original index. section 7.6.4
- At the current destination index, handle removals, noops, and additions first. If the desired item instead appears later in the working array, move it. section 7.6.2 section 7.6.4
- In `moveItem(item, toIndex)`, find the current position, emit the move operation, and splice both the item and its saved original index to the destination. section 7.6.4
Listing 7.15 Detecting whether an operation is addition (utils/arrays.js)
class ArrayWithOriginalIndices {
// --snip-- //
moveItem(item, toIndex) {
const fromIndex = this.findIndexFrom(item, toIndex) #1
const operation = { #2
op: ARRAY_DIFF_OP.MOVE,
originalIndex: this.originalIndexAt(fromIndex), #3
from: fromIndex,
index: toIndex,
item: this.#array[fromIndex],
}
const [_item] = this.#array.splice(fromIndex, 1) #4
this.#array.splice(toIndex, 0, _item) #5
const [originalIndex] =
this.#originalIndices.splice(fromIndex, 1) #6
this.#originalIndices.splice(toIndex, 0, originalIndex) #7
return operation #8
}
}
The `moveItem()` listing shows why the item array and original-index array must move together. section 7.6.4
Not every changed position calls for a move. An item can fall into place when another item is removed or moved; a noop records its initial and final indices so its children can still be compared during recursive DOM patching. section 7.6.1

