Skip to content

Commit dd50739

Browse files
committed
[major] respectArrayOrder
1 parent 8415105 commit dd50739

File tree

3 files changed

+172
-85
lines changed

3 files changed

+172
-85
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,54 @@ const difference = diffler(before, after);
4747
console.log(difference); // { location: { from: "London", to: "Melbourne" } }
4848
```
4949

50+
## Options
51+
52+
> Experimental
53+
54+
```shell
55+
npm i diffler@next
56+
```
57+
58+
### `respectArrayOrder` defaults to `true`
59+
60+
If you don't care about the order of an array you can disable like so:
61+
62+
```js
63+
const diffler = require("diffler");
64+
65+
const before = { name: "omgaz", locations: ["London", "Melbourne"] };
66+
const after = { name: "omgaz", locations: ["Melbourne", "London"] };
67+
68+
const difference = diffler(before, after, { respectArrayOrder: false });
69+
console.log(difference); // {}
70+
```
71+
72+
However, be aware that additions and removals change the overall shape of the array and so will be seen as an entire array change AFTER the addition and removal.
73+
74+
```js
75+
const diffler = require("diffler");
76+
77+
const before = { name: "omgaz", locations: ["London", "Hong Kong", "Melbourne"] };
78+
const after = { name: "omgaz", locations: ["London", "Melbourne", "Hong Kong" ] };
79+
80+
const difference = diffler(before, after, { respectArrayOrder: false });
81+
console.log(difference); // { locations: { 1: { from: "Hong Kong", to: "Melbourne" }, 2: { from: "Melbourne", to: "Hong Kong" }
82+
```
83+
84+
My advice is to use associative arrays if you do not care about order.
85+
86+
```js
87+
const diffler = require("diffler");
88+
89+
const before = { name: "omgaz", locations: { Melbourne: "Melbourne", London: "London" } };
90+
const after = { name: "omgaz", locations: { London: "London", Melbourne: "Melbourne" } };
91+
92+
const difference = diffler(before, after, { respectArrayOrder: false });
93+
console.log(difference); // { }
94+
```
95+
96+
Maybe in the future, diffler will do this internally and be able to return array new array indexes for these values, it is still my current belief that arrays are ordered and should preserve order.
97+
5098
## Tests
5199

52100
[![Build Status](https://travis-ci.org/omgaz/diffler.svg?branch=master)](https://travis-ci.org/omgaz/diffler)

src/index.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
*/
55

66
function isArray(toCheck) {
7-
return typeof toCheck === 'object' && Boolean(toCheck.length);
7+
return typeof toCheck === "object" && Boolean(toCheck.length);
88
}
99

1010
function isPrimitive(toCheck) {
1111
return toCheck !== Object(toCheck);
1212
}
1313

14-
function toPrimitive(val) {
15-
return isPrimitive(val) ? val : JSON.stringify(val);
14+
function validate(val) {
15+
if (isPrimitive(val)) return val;
16+
throw new Error("Cannot ignore array ordering on non-primitive values");
1617
}
1718

1819
var defaultOptions = {
@@ -33,7 +34,7 @@ function diffler(obj1, obj2, options = defaultOptions) {
3334

3435
// Iterate over obj1 looking for removals and differences in existing values
3536
for (var key in obj1) {
36-
if (obj1.hasOwnProperty(key) && typeof obj1[key] !== 'function') {
37+
if (obj1.hasOwnProperty(key) && typeof obj1[key] !== "function") {
3738
var obj1Val = obj1[key],
3839
obj2Val = obj2[key];
3940

@@ -46,14 +47,20 @@ function diffler(obj1, obj2, options = defaultOptions) {
4647
}
4748

4849
// If property is an object then we need to recursively go down the rabbit hole
49-
else if (typeof obj1Val === 'object') {
50+
else if (typeof obj1Val === "object") {
5051
var obj1ValForDiff = obj1Val;
5152
var obj2ValForDiff = obj2Val;
52-
if (!options.respectArrayOrder && isArray(obj1Val) && isArray(obj2Val)) {
53-
obj1ValForDiff = obj1Val.map(toPrimitive).sort();
54-
obj2ValForDiff = obj2Val.map(toPrimitive).sort();
53+
if (isArray(obj1Val) && isArray(obj2Val)) {
54+
// TODO: This is messy, but I've found a bug with arrays of mixed types
55+
// I need to clean this up later.
56+
obj1Val.map(validate);
57+
obj2Val.map(validate);
58+
if (!options.respectArrayOrder) {
59+
obj1ValForDiff = obj1Val.sort();
60+
obj2ValForDiff = obj2Val.sort();
61+
}
5562
}
56-
var tempDiff = diffler(obj1ValForDiff, obj2ValForDiff);
63+
var tempDiff = diffler(obj1ValForDiff, obj2ValForDiff, options);
5764
if (Object.keys(tempDiff).length > 0) {
5865
if (tempDiff) {
5966
diff[key] = tempDiff;
@@ -73,7 +80,7 @@ function diffler(obj1, obj2, options = defaultOptions) {
7380

7481
// Iterate over obj2 looking for any new additions
7582
for (key in obj2) {
76-
if (obj2.hasOwnProperty(key) && typeof obj2[key] !== 'function') {
83+
if (obj2.hasOwnProperty(key) && typeof obj2[key] !== "function") {
7784
var obj1Val = obj1[key],
7885
obj2Val = obj2[key];
7986

0 commit comments

Comments
 (0)