Reputation: 172
I have two nested JSON objects
//Json object1
{
"version": "1",
"user": {
"id": 123
}
}
//Json object2 =
{
"version": "1",
"user": {
"i": 123
}
}
1)It should only check for keys and not values during comparison. So above should return false and below should return true 2) It should also follow the structure say user.id is not the same as just id.
//Json object1
{
"version": "1",
"user": {
"id": 123
}
}
//Json object2
{
"version": "1",
"user": {
"id": 12
}
}
I have tried the code below but to no avail
exports.compareObjects = async(model, response) => {
switch (Object.prototype.toString.call(model)) {
case '[object]':
var x;
var mKeys = Object.keys(model);
for (x in mKeys) {
return this.compareObjects(Object.keys(model)[x], Object.keys(response)[x]);
}
break;
case '[object Object]':
var x1;
var mKeys1 = Object.keys(model);
for (x1 in mKeys1) {
return this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);
}
break;
case '[object Array]':
return this.compareObjects(model[0], response[0]);
// case '[object String]':
// return model === response;
default:
return true;
}
};
Upvotes: 2
Views: 1290
Reputation: 128
var compareObjects = (model, response) => {
switch (Object.prototype.toString.call(model)) {
case '[object]':
var x;
var mKeys = Object.keys(model);
for (x in mKeys) {
return this.compareObjects(Object.keys(model)[x], Object.keys(response)[x]);
}
break;
case '[object Object]':
var x1;
var mKeys1 = Object.keys(model);
for (x1 in mKeys1) {
let t = this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);
if(!t){
return false
}
if(typeof model[mKeys1[x1]] == "object"){
return this.compareObjects(model[mKeys1[x1]], response[mKeys1[x1]])
}
}
case '[object Array]':
return this.compareObjects(model[0], response[0]);
case '[object String]':
return model === response;
default:
return true;
}
};
let a = {
"version": "1",
"user": {
"id": 123,
"n":"d",
"j":{
"ns":"m"
}
}
}
let b = {
"version": "1",
"user": {
"id": 123,
"n":"d",
"j":{
"ns":"m"
}
}
}
var t = compareObjects(a,b)
console.log(t)
Upvotes: 0
Reputation: 4050
This uses a recursive key search to build out an array of keys in each object you want to compare.
It tests fairly strict equality (no extra keys in either object)
let obj1 = JSON.parse(`{
"version": "1",
"user": {
"id": 123
}
}`);
let obj2 = JSON.parse(`{
"version": "1",
"user": {
"i": 123
}
}`);
let obj3 = JSON.parse(`{
"version": "1",
"user": {
"id": 123
}
}`);
let obj4 = JSON.parse(`{
"version": "1",
"user": {
"id": 12
}
}`);
let test1 = structureIsEqual(obj1, obj2);
let test2 = structureIsEqual(obj3, obj4);
console.log('Structure of first two match: ' + test1);
console.log('Structure of second two match: ' + test2);
function structureIsEqual(obj1, obj2) {
let tree1 = getKeys(obj1).sort();
let tree2 = getKeys(obj2).sort();
if(tree1.length !== tree2.length)
return false;
let mismatch = tree1.find((x, idx) => tree2[idx] !== x);
return !mismatch;
}
function getKeys(obj) {
return recursiveKeys(obj, [], []);
}
function recursiveKeys(obj, result, todo, root = '') {
Object.keys(obj).forEach(key => {
if(typeof obj[key] === 'object') {
result.push(root + key);
todo.push({ obj: obj[key], root: root + key + '.' });
} else {
result.push(root + key);
}
});
if(todo.length > 0) {
let todoItem = todo.pop();
return recursiveKeys(todoItem.obj, result, todo, todoItem.root);
}else {
return result;
}
}
Upvotes: 2
Reputation: 670
Could be you could fix it by this line
return this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);
Instead do
return this.compareObjects(model[x1], response[x1]);
I would do it like this 1. you only need to compare objects (all other dont have keys) 2. recurse if value is also object
function compare(obj,model){
let keys=Object.keys(model)
let thisLevelOK=true
for (let key in keys.length){
if (obj[key]===undefined){
thisLevelOK=false
break
} else if (model[key].toString()=="[object Object]" && compare(obj[key],model[key])==false){
thisLevelOK=false
break
}
}
//in case obj has more keys then model
thisLevelOK=thisLevelOK && compare(model,obj)
return thisLevelOK
}
Upvotes: 0