I am having a complex JSON object which I want to compare like below :
$scope.new = [
{
"name": "Node-1",
"isParent": true,
"text" : [
{
"str" : "This is my first Node-1 string",
"parent":[]
},
{
"str" : "This is my second Node-1 string",
"parent":[]
}],
"nodes": [
{
"name": "Node-1-1",
"isParent": false,
"text" : [
{
"str" : "This is my first Node-1-1 string",
"parent":[]
},
{
"str" : "This is my second Node-1-1 string",
"parent":[]
}],
"nodes": [
{
"name": "Node-1-1-1",
"isParent": false,
"text" : [
{
"str" : "This is my first Node-1-1-1 string",
"parent":[]
},
{
"str" : "This is my second Node-1-1-1 string",
"parent":[]
}],
"nodes": []
}
]
}
]
}
]
But while comparing I want to ignore 1 property also but as I am using Angular.js I don't see any option in angular.equal
which will omit that property while comparing 2 object.
console.log(angular.equals($scope.new,$scope.copy));
So while doing research I came with below answer which is using lodash having emit option but problem is I guess omit create a copy and I guess I will have performance degradation in case of lodash.
Exclude some properties in comparison using isEqual() of lodash
So now I am thinking to convert object so string and then do comparison and I guess that will be fast but problem is how I will omit that property while string comparison?
Something like this:
var str1 = JSON.stringify(JSON.stringify($scope.new));
var str2 = JSON.stringify(JSON.stringify($scope.copy));
console.log(str1==str2);
Note: I want to ignore isParent
property while comparing 2 object.
What would be the best way to do compare 2 object?
Converting to strings is not the best approach in these cases. Keep them as objects.
Using loadash:
const propertiesToExclude = ['isParent'];
let result = _.isEqual(
_.omit(obj1, propertiesToExclude),
_.omit(obj2, propertiesToExclude)
);
Using plain AngularJS, create a copy of the objects removing the not needed properties and then compare them:
let firstObj = angular.copy(obj1);
let secondObj = angular.copy(obj2);
const propertiesToExclude = ['isParent'];
function removeNotComparatedProperties(obj) {
propertiesToExclude.forEach(prop => {
delete obj[prop];
});
}
removeNotComparatedProperties(firstObj);
removeNotComparatedProperties(secondObj);
angular.equals(firstObj, secondObj);
You can use lodash and override the standard comparator used for deep comparison if you use _.isEqualWith
:
var objA = {
isParent: true,
foo: {
isParent: false,
bar: "foobar"
}
};
var objB = {
isParent: false,
foo: {
isParent: true,
bar: "foobar"
}
};
var comparator = function(left, right, key) {
if (key === 'isParent') return true; // if the key is 'isParent', mark the values equal
else return undefined; // else fall back to the default behavior
}
var isEqual = _.isEqualWith(objA, objB, comparator);
console.log(isEqual); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
To exclude multiple properties, extend the comparator function accordingly:
var comparator = function(left, right, key) {
if (key === 'isParent' || key === 'anotherKey') return true;
else return undefined;
}
You could also use a number of different approaches syntactically, depending on what you prefer -- a switch statement, an array that you iterate...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With