diff --git a/README.md b/README.md
index 5d0fba8..c634335 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,6 @@ This library compares two arrays or objects and returns a full diff of their dif


-
## WHY YOU SHOULD USE THIS LIBRARY
All other existing solutions return a strange diff format that often requires additional parsing. They are also limited to object comparison. 👎
@@ -19,7 +18,6 @@ All other existing solutions return a strange diff format that often requires ad
I am grateful to the generous donors of **Superdiff**!
-

@@ -235,11 +233,13 @@ You can add a third `options` parameter to `getListDiff`.
{
showOnly?: ("added" | "deleted" |Â "moved" | "updated" | "equal")[], // [] by default
referenceProperty?: string; // "" by default
+ ignoreArrayOrder?: boolean // false by default,
}
```
- `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`).
- `referenceProperty` will consider an object to be updated instead of added or deleted if one of its properties remains stable, such as its `id`. This option has no effect on other datatypes.
+- `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order.
### isEqual()
diff --git a/package.json b/package.json
index f99ba16..1bcc421 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,8 @@
"scripts": {
"build": "tsup --dts --format esm,cjs",
"publish": "npm publish --access=public",
- "test": "jest"
+ "test": "jest",
+ "tsc": "tsc --noEmit"
},
"devDependencies": {
"@babel/preset-env": "^7.23.8",
diff --git a/src/list-diff.ts b/src/list-diff.ts
index ffaf55e..52e21f6 100644
--- a/src/list-diff.ts
+++ b/src/list-diff.ts
@@ -1,10 +1,4 @@
-import {
- LIST_STATUS,
- ListData,
- ListDiff,
- ListDiffStatus,
- ListOptions,
-} from "./model";
+import { LIST_STATUS, ListDiff, ListDiffStatus, ListOptions } from "./model";
import { isEqual, isObject } from "./utils";
function getLeanDiff(
@@ -72,6 +66,7 @@ export const getListDiff =
(
showOnly: [],
referenceProperty: undefined,
considerMoveAsUpdate: false,
+ ignoreArrayOrder: false,
}
): ListDiff => {
if (!prevList && !nextList) {
@@ -110,7 +105,7 @@ export const getListDiff = (
prevIndexMatches.push(prevIndex);
}
const indexDiff = prevIndex === -1 ? null : i - prevIndex;
- if (indexDiff === 0) {
+ if (indexDiff === 0 || options.ignoreArrayOrder) {
let nextStatus = LIST_STATUS.EQUAL;
if (isReferencedObject(nextValue, options.referenceProperty)) {
if (!isEqual(prevList[prevIndex], nextValue)) {
diff --git a/src/model.ts b/src/model.ts
index ea17db8..81c75d3 100644
--- a/src/model.ts
+++ b/src/model.ts
@@ -55,6 +55,7 @@ export type ListOptions = {
showOnly?: Array;
referenceProperty?: string;
considerMoveAsUpdate?: boolean;
+ ignoreArrayOrder?: boolean;
};
export type ListDiff = {
diff --git a/test/list-diff.test.ts b/test/list-diff.test.ts
index e52d410..7c38a8f 100644
--- a/test/list-diff.test.ts
+++ b/test/list-diff.test.ts
@@ -697,4 +697,95 @@ describe("getListDiff", () => {
],
});
});
+ it("consider moved values as equal if they have not changed and ignoreArrayOrder option is true", () => {
+ expect(
+ getListDiff(
+ [
+ { id: 3, name: "nina", hobbies: ["swiming"] },
+ { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
+ { id: 2, name: "jack", hobbies: ["coding"] },
+ ],
+ [
+ { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
+ { id: 2, name: "jack", hobbies: ["coding"] },
+ { id: 3, name: "nina", hobbies: ["swiming"] },
+ ],
+ {
+ ignoreArrayOrder: true,
+ }
+ )
+ ).toStrictEqual({
+ type: "list",
+ status: "equal",
+ diff: [
+ {
+ value: { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
+ prevIndex: 1,
+ newIndex: 0,
+ indexDiff: -1,
+ status: "equal",
+ },
+ {
+ value: { id: 2, name: "jack", hobbies: ["coding"] },
+ prevIndex: 2,
+ newIndex: 1,
+ indexDiff: -1,
+ status: "equal",
+ },
+ {
+ value: { id: 3, name: "nina", hobbies: ["swiming"] },
+ prevIndex: 0,
+ newIndex: 2,
+ indexDiff: 2,
+ status: "equal",
+ },
+ ],
+ });
+ });
+ it("consider moved values as updated if they have changed and ignoreArrayOrder option is true", () => {
+ expect(
+ getListDiff(
+ [
+ { id: 3, name: "nina", hobbies: ["swiming"] },
+ { id: 1, name: "joseph", hobbies: ["golf", "fishing"] },
+ { id: 2, name: "jack", hobbies: ["coding"] },
+ ],
+ [
+ { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
+ { id: 2, name: "jack", hobbies: ["coding"] },
+ { id: 3, name: "nina", hobbies: ["swiming"] },
+ ],
+ {
+ ignoreArrayOrder: true,
+ referenceProperty: "id",
+ }
+ )
+ ).toStrictEqual({
+ type: "list",
+ status: "updated",
+ diff: [
+ {
+ value: { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
+ prevIndex: 1,
+ newIndex: 0,
+ indexDiff: -1,
+ status: "updated",
+ },
+ {
+ value: { id: 2, name: "jack", hobbies: ["coding"] },
+ prevIndex: 2,
+ newIndex: 1,
+ indexDiff: -1,
+ status: "equal",
+ },
+ {
+ value: { id: 3, name: "nina", hobbies: ["swiming"] },
+ prevIndex: 0,
+ newIndex: 2,
+ indexDiff: 2,
+ status: "equal",
+ },
+ ],
+ });
+ });
});