Detecting Moved Items in JSON Arrays
Learn how JSON diff tools detect when array items have been reordered rather than changed. Understand move detection algorithms and how to reduce noise in array diffs.
Detailed Explanation
When an array element changes position without being modified, a naive diff algorithm reports it as a removal at the old index and an addition at the new index. Move detection is an advanced feature that recognizes this pattern and reports a single "move" operation instead.
The move detection problem:
// Before
{
"steps": [
{ "id": "build", "name": "Build" },
{ "id": "test", "name": "Test" },
{ "id": "lint", "name": "Lint" },
{ "id": "deploy", "name": "Deploy" }
]
}
// After
{
"steps": [
{ "id": "lint", "name": "Lint" },
{ "id": "build", "name": "Build" },
{ "id": "test", "name": "Test" },
{ "id": "deploy", "name": "Deploy" }
]
}
Without move detection (index-based diff):
- Index 0: changed from
buildtolint - Index 1: changed from
testtobuild - Index 2: changed from
linttotest
This is noisy and obscures the actual change: lint was moved from index 2 to index 0.
With move detection (identity-based diff using id):
lint: moved from index 2 to index 0
This accurately represents the single reordering operation that occurred.
How move detection works:
- Identity matching: The algorithm first matches elements across both arrays using a unique identifier (like
id). This establishes which elements are "the same" regardless of position. - Position comparison: For matched elements, their indices are compared. Elements at different indices are candidates for move operations.
- LCS optimization: The Longest Common Subsequence of matched elements determines which elements stayed in place and which moved. Elements not in the LCS are the ones that moved.
RFC 6902 JSON Patch:
The JSON Patch standard includes a "move" operation:
{ "op": "move", "from": "/steps/2", "path": "/steps/0" }
This is more concise and efficient than separate remove+add operations, especially for large arrays.
When move detection matters:
- CI/CD pipeline steps: Reordering build steps is a common change that should be clearly visible.
- Priority lists: Tasks or queue items reordered by priority.
- Column layouts: UI configuration where the order of displayed columns changes.
Use Case
Reviewing a CI/CD pipeline configuration change to confirm that build steps were only reordered (moving linting before building) without any steps being added or removed.