Skip to content

Commit 7978b17

Browse files
authored
fix(core): correct element removal order in unsets (#556)
When unsetting multiple array elements using range expressions, elements were being removed in forward order causing index shifting issues. This resulted in subsequent removals targeting incorrect indices. Now processes unset matches in reverse order to maintain index stability during removal, ensuring correct behavior for range operations like `items[1:3]`. Fixes array unset operations that were removing wrong elements due to index shifting during the removal process.
1 parent 15e8ee2 commit 7978b17

File tree

2 files changed

+4
-1
lines changed

2 files changed

+4
-1
lines changed

packages/core/src/document/patchOperations.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ describe('unset', () => {
668668
it('unsets multiple array elements when using a range', () => {
669669
const input = {items: [1, 2, 3, 4, 5]}
670670
const output = unset(input, ['items[1:3]'])
671-
expect(output).toEqual({items: [1, 3, 5]})
671+
expect(output).toEqual({items: [1, 4, 5]})
672672
})
673673

674674
it('leaves input unchanged if no path expression matches', () => {

packages/core/src/document/patchOperations.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,9 @@ export function unset<R>(input: unknown, pathExpressions: string[]): R
484484
export function unset(input: unknown, pathExpressions: string[]): unknown {
485485
const result = pathExpressions
486486
.flatMap((pathExpression) => jsonMatch(input, pathExpression))
487+
// ensure that we remove in the reverse order the paths were found in
488+
// this is necessary for array unsets so the indexes don't change as we unset
489+
.reverse()
487490
.reduce((acc, {path}) => unsetDeep(acc, path), input)
488491

489492
return ensureArrayKeysDeep(result)

0 commit comments

Comments
 (0)