Note:
- Please use version 0.2.5 for projects using Angular 11.0 and below.
- Please use version 0.3.0+ for Angular 12.0+ projects.
- Version 0.4.0+ supports use in Web Workers (see example project in this repository).
- Version 0.4.2 is malformed and should not be used.
- Version 0.4.3+ supports Standalone Components.
- Version 0.5.0 supports Angular 16.
- Version 1.0.0 supports Angular 17.
- Version 2.0.0 supports Angular 18.
- Version 3.0.0 supports Angular 19.
This is a package intended to provide a deep equals function for JavaScript objects without requiring numerous dependencies. Other packages which provide a deep equals function, like Lodash or deep-equal, require a large number of dependencies or they are themselves very large. This contributes to unnecessary bloat and, ultimately, poor application load performance.
Unlike deep-equal and Lodash, ngx-deep-equals-pure can correctly handle function properties. Furthermore, ngx-deep-equals-pure properly determines equality for arrays of complex objects when the order of the data differs where deep-equal and Lodash fail to do so.
Repository: https://github.com/puckowski/deepequalspure
Bugs: https://github.com/puckowski/deepequalspure/issues
The minified ES2015 size of ngx-deep-equals-pure is 9.18KB which includes ESM5, ESM2015, FESM5, and FESM2015 bundles.
ngx-deep-equals-pure | deep-equal | Lodash |
---|---|---|
9.18KB | 3.44KB | 528KB |
https://www.npmjs.com/package/ngx-deep-equals-pure
In the appropriate module, such as AppModule
, add the following to providers
:
providers: [NgxDeepEqualsPureService],
In a component part of a module where NgxDeepEqualsPureService is provided, inject the deep equals service in the constructor like so:
constructor(private ngxDeepEquals: NgxDeepEqualsPureService) {
Then use NgxDeepEqualsPure like so:
this.ngxDeepEquals.deepEquals(this.obj1, this.obj2);
Alternatively, construct a standalone component like the following:
import { Component } from '@angular/core';
import { NgxDeepEqualsPureModule, NgxDeepEqualsPureService } from 'NgxDeepEqualsPure';
@Component({
selector: 'app-standalone-test',
templateUrl: './standalone-test.component.html',
styleUrls: ['./standalone-test.component.scss'],
standalone: true,
imports: [NgxDeepEqualsPureModule]
})
export class StandaloneTestComponent {
private obj8: any = { b: 'a', c: 2 };
private obj9: any = { c: 2, b: 'a' };
public isStandaloneMatch: boolean;
constructor(private ngxDeepEquals: NgxDeepEqualsPureService) {
this.isStandaloneMatch = this.ngxDeepEquals.deepEquals(this.obj8, this.obj9);
}
}
The following is the latest performance result of 2,000 comparisons run in a web worker.
ngx-deep-equals-pure | deep-equal | Lodash isEqual |
---|---|---|
0.023 | 0.006 | 0.091 |
0.007 | 0.008 | 0.107 |
0.006 | 0.004 | 0.106 |
0.006 | 0.001 | 0.115 |
0.006 | 0.001 | 0.115 |
0.006 | 0.001 | 0.117 |
0.005 | 0.001 | 0.117 |
0.006 | 0.001 | 0.12 |
0.006 | 0.001 | 0.118 |
0.006 | 0.001 | 0.117 |
0.006 | 0.001 | 0.117 |
0.006 | 0.001 | 0.116 |
0.006 | 0.001 | 0.118 |
0.006 | 0.001 | 0.118 |
0.006 | 0.001 | 0.118 |
0.005 | 0.001 | 0.118 |
0.006 | 0.001 | 0.119 |
0.006 | 0.001 | 0.118 |
0.006 | 0 | 0.118 |
0.006 | 0.002 | 0.117 |
Avg: 0.0068s | Avg: 0.00175s | Avg: 0.1149s |
this.isMatch.push(this.deep.deepEquals(obj1, obj2));
this.isMatch.push(this.deep.deepEquals(obj1, obj3));
this.isMatch.push(this.deep.deepEquals(obj1, obj4));
this.isMatch.push(this.deep.deepEquals(obj1, obj5));
this.isMatch.push(this.deep.deepEquals(obj1, obj6));
this.isMatch.push(this.deep.deepEquals(obj1, obj7));
this.isMatch.push(this.deep.deepEquals(obj8, obj9));
this.isMatchLodash.push(_.isEqual(obj1, obj2));
this.isMatchLodash.push(_.isEqual(obj1, obj3));
this.isMatchLodash.push(_.isEqual(obj1, obj4));
this.isMatchLodash.push(_.isEqual(obj1, obj5));
this.isMatchLodash.push(_.isEqual(obj1, obj6));
this.isMatchLodash.push(_.isEqual(obj1, obj7));
this.isMatchLodash.push(_.isEqual(obj8, obj9));
this.isMatchDeepEqual.push(deepEqual(obj1, obj2));
this.isMatchDeepEqual.push(deepEqual(obj1, obj3));
this.isMatchDeepEqual.push(deepEqual(obj1, obj4));
this.isMatchDeepEqual.push(deepEqual(obj1, obj5));
this.isMatchDeepEqual.push(deepEqual(obj1, obj6));
this.isMatchDeepEqual.push(deepEqual(obj1, obj7));
this.isMatchDeepEqual.push(deepEqual(obj8, obj9));
# | Actual | ngx-deep-equals-pure | deep-equal | Lodash isEqual |
---|---|---|---|---|
1 | true | true | false | false |
2 | false | false | false | false |
3 | false | false | false | false |
4 | false | false | false | false |
5 | false | false | false | false |
6 | true | true | false | false |
7 | true | true | true | true |
const obj1: any = {
b: () => {
console.log('foo');
},
e: 'abcbc',
a: [
{ 'a': 12.7 },
{ 'c': 37.6 }
],
c: 126.8,
f: ['f', 'a'],
g: [
{ t: () => { console.log('h'); }, g: 'a', j: 12 },
['b', 2, { p: '123' }],
'789',
12.6,
809,
() => { console.log('er'); }
]
};
const obj2: any = {
g: [
[{ p: '123' }, 2, 'b'],
'789',
12.6,
() => { console.log('er'); },
{ g: 'a', t: () => { console.log('h'); }, j: 12 },
809
],
e: 'abcbc',
b: () => {
console.log('foo');
},
a: [
{ 'c': 37.6 },
{ 'a': 12.7 }
],
f: ['f', 'a'],
c: 126.8
};
const obj3: any = {
g: [
[{ p: '123' }, 2, 'b'],
'789',
12.6,
() => { console.log('er'); },
{ t: () => { console.log('h'); }, j: 12 },
809
],
e: 'abcbc',
b: () => {
console.log('foo');
},
a: [
{ 'c': 37.6 },
{ 'a': 12.7 }
],
f: ['f', 'a'],
c: 126.8
};
const obj4: any = {
g: [
[{ p: '123' }, 2, 'b'],
'789',
12.6,
() => { console.log('er'); },
{ g: '6', t: () => { console.log('h'); }, j: 12 },
809
],
e: 'abcbc',
b: () => {
console.log('foo');
},
a: [
{ 'c': 37.6 },
{ 'a': 12.7 }
],
f: ['f', 'a'],
c: 126.8
};
const obj5: any = {
g: [
[{ u: '123' }, 2, 'b'],
'789',
12.6,
() => { console.log('er'); },
{ g: 'a', t: () => { console.log('h'); }, j: 12 },
809
],
e: 'abcbc',
b: () => {
console.log('foo');
},
a: [
{ 'c': 37.6 },
{ 'a': 12.7 }
],
f: ['f', 'a'],
c: 126.8
};
const obj6: any = {
g: [
[{ p: '123' }, 2, 'b'],
'789',
12.6,
() => { console.log('er'); },
{ g: 'a', y: () => { console.log('h'); }, j: 12 },
809
],
e: 'abcbc',
b: () => {
console.log('foo');
},
a: [
{ 'c': 37.6 },
{ 'a': 12.7 }
],
f: ['f', 'a'],
c: 126.8
};
const obj7: any = {
b: () => {
console.log('foo');
},
e: 'abcbc',
a: [
{ 'a': 12.7 },
{ 'c': 37.6 }
],
c: 126.8,
f: ['f', 'a'],
g: [
{ t: () => { console.log('h'); }, g: 'a', j: 12 },
['b', 2, { p: '123' }],
'789',
12.6,
809,
() => { console.log('er'); }
]
};
const obj8: any = { b: 'a', c: 2 };
const obj9: any = { c: 2, b: 'a' };
Use command:
ng build NgxDeepEqualsPure --configuration production
Use command:
ng serve
Then navigate to localhost:4200 in your preferred browser.
Note: It may be necessary to run the build command before trying to run the benchmark.
See the GitHub repository at https://github.com/puckowski/deepequalspure for example usage of ngx-deep-equals-pure in an Angular application and for example usage in a Web Worker.