yujianrong / fast-array-diff Goto Github PK
View Code? Open in Web Editor NEWNode module to find the same/diff of two arrays.
License: MIT License
Node module to find the same/diff of two arrays.
License: MIT License
When I run the following code I expect the results to be empty however they are not:
const arrayDiff = require('fast-array-diff');
const result = arrayDiff.diff(
[{ id: '1234' }, { id: '5678' }],
[{ id: '5678' }, { id: '1234' }],
areEqual,
);
function areEqual(objA, objB) {
return objA.id === objB.id;
}
The result is: "{"removed":[{"id":"5678"}],"added":[{"id":"5678"}]}"
When the objects are sorted then it works as expected.
Im using the lib find find differences between objects.
When i compare with numbers it works as intended but when i want to compare with strings or bools something strange happens.
Example:
const arr1 = [
{
id: "1",
description: "1",
blaat: "blaat",
active: true
},
{
id: "2",
description: "2",
blaat: "blaat",
active: true
}
];
const arr2 = [
{
id: "1",
description: "1",
blaat: "blaat",
active: true
},
{
id: "2",
description: "2",
blaat: "blaat",
active: true
},
{
id: "3",
description: "3",
blaat: "blaat",
active: true
}
];
const diff1 = diff(arr1, arr2, (a, b) => a.description === b.description);
const diff2 = diff(arr1, arr2, (a, b) => a.blaat === b.blaat);
You would images both diff1
and diff2
are the same because in both cases an extra object was added to arr2.
But this is the response :
diff1
{
added: [
{
id: '3',
description: '3',
blaat: 'blaat',
active: true
}
],
removed: []
}
diff2
{
added: [
{
id: '1',
description: '1',
blaat: 'blaat',
active: true
}
],
removed: []
}
The first diff is comparing on description
containing a number, and returns object with ID 3, and this is correct.
The second diff is comparing on blaat
containing a text, but this returns object with ID 1, that exists in both array's.
Same issue is when comparing on active
which is a bool
Am i missing something?
Please analyze the possibility of not re-creating a new object when applying the patch. I want to keep the old reference to the object.
Consider something like:
export interface DiffData<Ta, Tb> {
removed: Ta[];
added: Tb[];
}
export declare function diff<Ta, Tb>(a: Ta[], b: Tb[], compareFunc?: (ia: Ta, ib: Tb) => boolean): DiffData<Ta, Tb>;
My concrete use case is: I have some records in the db and new records coming in. The records in the db have id
s, the new ones do not. I need the ids to know what records I want to archive in the db. Now I can't use this package without some workaround.
import { diff } from "fast-array-diff";
const oldArray = [
{
name: "Lucy"
},
{
name: "Tom"
}
];
const newArray = [
{
name: "Tom"
},
{
name: "Lucy"
}
];
const compare = (a, b) => a.name === b.name;
console.log(diff(oldArray, newArray, compare));
{
added: [],
removed: []
}
{
added: [{ name: 'Tom' }],
removed: [{ name: 'Tom' }]
}
Environment | Info |
---|---|
fast-array-diff | v1.0.1 |
I have arrays of lengths92054 89384 29287 68962 61669 containing just integers.
This code never returns:
.add("diff.diff",() => {
let result = diff.diff([arg1,arg2,arg3,arg4,arg5]).added;
size = result.length;
})
This code does return using short arrays:
.add("diff.diff short",() => {
const arg1 =[1,2], arg2 = [1,2,3];
let result = diff.diff([arg1,arg2]).added;
size = result.length;
})
As does this using a different library and the original long arrays:
add("difference",() => {
const result = arg1.difference(arg2,arg3,arg4,arg5);
size = result.length;
})
I was recently looking into the source code and test cases of the fast-array-diff
library and noticed that there doesn't appear to be any sorting applied to the input arrays during the comparison process. While testing the library, I encountered an issue where providing two identical arrays sorted differently resulted in incorrect results.
Is this behavior expected, or is it a bug? If it is expected, could you please provide some insights into why the library behaves this way and whether it is by design?
I believe it would be helpful to update the library's documentation with examples that clarify this behavior, as it can be crucial for users to understand how the library handles cases where input arrays are unsorted.
Thanks
At a glance it doesn't seem as though the library is mutating the arrays at all. It would be safer to use readonly T[]
than T[]
.
I'm trying to speed up our existing code using the diff
function by replacing
const factorSetsToArchive = existingFactorSets.filter(
(existingFactorSet) => !newFactorSets.find((newFactorSet) => areFactorSetsEqual(existingFactorSet, newFactorSet))
);
const factorSetsToCreate = newFactorSets.filter(
(factorSet) => !existingFactorSets.find((existingFactorSet) => areFactorSetsEqual(existingFactorSet, factorSet))
);
with
const { added: factorSetsToCreate, removed: factorSetsToArchive } = diff(
existingFactorSets,
newFactorSets,
areFactorSetsEqual
);
Using our original code I am getting empty arrays for both factorSetsToArchive
and factorSetsToCreate
. Using the diff
function I am getting values in there. The values looked identical to me so I picked a sample from each list and ran the compare function areFactorSetsEqual
on them, which returned true. So they shouldn't have been in that list to begin with. Looks to me like there might be a bug.
If you need more info I can share the comparator function, but I can't share any actual data since it is licensed. The function doesn't seem to be causing the issue though.
d.getPatch('\u{1f4a8}\u{1f4a9}c', '\u{1f4a8}bc')
// [
// { type: 'remove', oldPos: 2, newPos: 2, items: [ '�', '�' ] },
// { type: 'add', oldPos: 4, newPos: 2, items: [ 'b' ] }
// ]
I've got two arrays like this:
const oldVal = ['item1', 'item2', 'item3'];
const newVal = ['item4', 'item2', 'item3', 'foo'];
Running diff.getPatch(oldVal, newVal)
includes an add
row like {type: 'add', oldPos: 3, newPos: 3, items: ['foo']}
and when I do diff.applyPatch(newVal, patch)
it adds another foo
at the end.
Example CodePen (also written out down below): https://codepen.io/master-elodin/pen/MWbKKGL
import * as diff from "https://cdn.skypack.dev/[email protected]";
const oldVal = ['item1', 'item2', 'item3'];
const newVal = ['item4', 'item2', 'item3', 'foo'];
const patch = diff.getPatch(oldVal, newVal);
console.log(diff.applyPatch(newVal, patch));
// expected: ["item4", "item2", "item3", "foo"]
// actual: ["item4", "item2", "item3", "foo", "foo"]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.