Skip to content

Commit 6daef58

Browse files
authored
feat: add ignoreArrayOrder option to getListDiff (#23)
1 parent 88a11d3 commit 6daef58

File tree

5 files changed

+99
-11
lines changed

5 files changed

+99
-11
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ This library compares two arrays or objects and returns a full diff of their dif
88
![NPM Downloads](https://img.shields.io/npm/dy/%40donedeal0%2Fsuperdiff?logo=npm)
99
![GitHub Tag](https://img.shields.io/github/v/tag/DoneDeal0/superdiff?label=latest%20release)
1010

11-
1211
## WHY YOU SHOULD USE THIS LIBRARY
1312

1413
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
1918

2019
I am grateful to the generous donors of **Superdiff**!
2120

22-
2321
<div style="display: flex;>
2422
2523
<a href="https://github.com/AlexisAnzieu" target="_blank"><img alt="AlexisAnzieu" src="https://github.com/DoneDeal0/superdiff/assets/43271780/8e9fb627-36ec-479d-87d4-3ca2cb2a796c" width="72px" height="72px"/></a>
@@ -235,11 +233,13 @@ You can add a third `options` parameter to `getListDiff`.
235233
{
236234
showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default
237235
referenceProperty?: string; // "" by default
236+
ignoreArrayOrder?: boolean // false by default,
238237
}
239238
```
240239

241240
- `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`).
242241
- `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.
242+
- `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.
243243

244244
### isEqual()
245245

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"scripts": {
3434
"build": "tsup --dts --format esm,cjs",
3535
"publish": "npm publish --access=public",
36-
"test": "jest"
36+
"test": "jest",
37+
"tsc": "tsc --noEmit"
3738
},
3839
"devDependencies": {
3940
"@babel/preset-env": "^7.23.8",

src/list-diff.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import {
2-
LIST_STATUS,
3-
ListData,
4-
ListDiff,
5-
ListDiffStatus,
6-
ListOptions,
7-
} from "./model";
1+
import { LIST_STATUS, ListDiff, ListDiffStatus, ListOptions } from "./model";
82
import { isEqual, isObject } from "./utils";
93

104
function getLeanDiff(
@@ -72,6 +66,7 @@ export const getListDiff = <T>(
7266
showOnly: [],
7367
referenceProperty: undefined,
7468
considerMoveAsUpdate: false,
69+
ignoreArrayOrder: false,
7570
}
7671
): ListDiff => {
7772
if (!prevList && !nextList) {
@@ -110,7 +105,7 @@ export const getListDiff = <T>(
110105
prevIndexMatches.push(prevIndex);
111106
}
112107
const indexDiff = prevIndex === -1 ? null : i - prevIndex;
113-
if (indexDiff === 0) {
108+
if (indexDiff === 0 || options.ignoreArrayOrder) {
114109
let nextStatus = LIST_STATUS.EQUAL;
115110
if (isReferencedObject(nextValue, options.referenceProperty)) {
116111
if (!isEqual(prevList[prevIndex], nextValue)) {

src/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export type ListOptions = {
5555
showOnly?: Array<ListStatusTuple[number]>;
5656
referenceProperty?: string;
5757
considerMoveAsUpdate?: boolean;
58+
ignoreArrayOrder?: boolean;
5859
};
5960

6061
export type ListDiff = {

test/list-diff.test.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,4 +697,95 @@ describe("getListDiff", () => {
697697
],
698698
});
699699
});
700+
it("consider moved values as equal if they have not changed and ignoreArrayOrder option is true", () => {
701+
expect(
702+
getListDiff(
703+
[
704+
{ id: 3, name: "nina", hobbies: ["swiming"] },
705+
{ id: 1, name: "joe", hobbies: ["golf", "fishing"] },
706+
{ id: 2, name: "jack", hobbies: ["coding"] },
707+
],
708+
[
709+
{ id: 1, name: "joe", hobbies: ["golf", "fishing"] },
710+
{ id: 2, name: "jack", hobbies: ["coding"] },
711+
{ id: 3, name: "nina", hobbies: ["swiming"] },
712+
],
713+
{
714+
ignoreArrayOrder: true,
715+
}
716+
)
717+
).toStrictEqual({
718+
type: "list",
719+
status: "equal",
720+
diff: [
721+
{
722+
value: { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
723+
prevIndex: 1,
724+
newIndex: 0,
725+
indexDiff: -1,
726+
status: "equal",
727+
},
728+
{
729+
value: { id: 2, name: "jack", hobbies: ["coding"] },
730+
prevIndex: 2,
731+
newIndex: 1,
732+
indexDiff: -1,
733+
status: "equal",
734+
},
735+
{
736+
value: { id: 3, name: "nina", hobbies: ["swiming"] },
737+
prevIndex: 0,
738+
newIndex: 2,
739+
indexDiff: 2,
740+
status: "equal",
741+
},
742+
],
743+
});
744+
});
745+
it("consider moved values as updated if they have changed and ignoreArrayOrder option is true", () => {
746+
expect(
747+
getListDiff(
748+
[
749+
{ id: 3, name: "nina", hobbies: ["swiming"] },
750+
{ id: 1, name: "joseph", hobbies: ["golf", "fishing"] },
751+
{ id: 2, name: "jack", hobbies: ["coding"] },
752+
],
753+
[
754+
{ id: 1, name: "joe", hobbies: ["golf", "fishing"] },
755+
{ id: 2, name: "jack", hobbies: ["coding"] },
756+
{ id: 3, name: "nina", hobbies: ["swiming"] },
757+
],
758+
{
759+
ignoreArrayOrder: true,
760+
referenceProperty: "id",
761+
}
762+
)
763+
).toStrictEqual({
764+
type: "list",
765+
status: "updated",
766+
diff: [
767+
{
768+
value: { id: 1, name: "joe", hobbies: ["golf", "fishing"] },
769+
prevIndex: 1,
770+
newIndex: 0,
771+
indexDiff: -1,
772+
status: "updated",
773+
},
774+
{
775+
value: { id: 2, name: "jack", hobbies: ["coding"] },
776+
prevIndex: 2,
777+
newIndex: 1,
778+
indexDiff: -1,
779+
status: "equal",
780+
},
781+
{
782+
value: { id: 3, name: "nina", hobbies: ["swiming"] },
783+
prevIndex: 0,
784+
newIndex: 2,
785+
indexDiff: 2,
786+
status: "equal",
787+
},
788+
],
789+
});
790+
});
700791
});

0 commit comments

Comments
 (0)