比较 json 对象的结构 javascript



我正在编写一个测试函数邮递员,以检查 json 对象是否具有相同的键并且每个键具有相同的数据类型

我有 3 个 json 对象

var test1 = {
"abc" : 1,
"qwe" : "random",
"arrayExample" : [{"var1" : 11, "var2" : 22}, {"var1" : 21314, "var2" : 99}]
}

var test2 = {
"abc" : 3,
"qwe" : "Another String",
"arrayExample" : [{"var1": 435, "var2": 897}]
}

var test3 = {
"abc" : 46,
"qwe" : "Nothing special",
"arrayExample" : [{"var1": 098, "var9" : "string here"}]
}

我想测试键,每个键的值也属于同一类型。

例如,如果我的比较函数称为 compare,如果对象类型相同,则返回 true,

function compare(obj1, obj2){
<NEED HELP HERE>
}

那么我需要

compare(test1, test2) == true

compare(test1, test3) == compare(test2, test3) == false

因为

typeOf( test1["arrayExample"] ) = typeOf( test2["arrayExample"] ) = array of same JSON type

typeOf( test3["arrayExample"]) = array of different json type

如果您的问题仅涉及比较单个属性值,则可以执行以下操作:

  • 确保两个对象具有相同数量的键。
  • 确保同名属性的值类型相同。

const tests = {
4: {a: 1, b: "AA"},
5: {b: "BB", a: 2},
6: {a: 3, b: 999},
7: {a: 4, c: "CC"},
8: {a: 5, b: "DD", c: 999},
9: {a: 6, b: "EE", c: undefined}
};
const compare = (obj1, obj2) => {
let similar = true;
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
if (obj1Keys.length !== obj2Keys.length) {
similar = false;
} else {
obj1Keys.forEach(key => {
similar = (typeof obj1[key] === typeof obj2[key]);
});
}
return similar;
};
const check = (a, b) => {
console.log(`Test objects ${a} and ${b} are similar? ${compare(tests[a], tests[b])}`);
};
check(4, 5);
check(4, 6);
check(4, 7);
check(4, 8);
check(4, 9);

但是,对于数组属性,您可以使用上述整个过程对两个对象的同名属性数组中的所有数组元素组合执行递归检查。 例如,如果对象 1 的属性 "X" 有一个包含 3 个对象的数组,而对象 2 的属性 "X" 有一个包含 4 个对象的数组(总共 7 个对象), 递归地使用上面的检查将这 7 个对象中的第一个与其他所有 6 个对象进行比较,即比较

1&2、1&3、1&4、1&5、1&6 和 1&7。 虽然我还没有测试过它,虽然你的问题实际上并没有问这个问题,但这种方法实际上甚至应该适用于对象的子嵌套数组,即如果数组包含本身包含对象数组的对象,等等。这是因为代码的(可能是无限的)递归性质。

const tests = {
1: {
"abc" : 1,
"qwe" : "random",
"arrayExample" : [{"var1" : 11, "var2" : 22}, {"var1" : 21314, "var2" : 99}]
},
2: {
"abc" : 3,
"qwe" : "Another String",
"arrayExample" : [{"var1": 435, "var2": 897}]
},
3: {
"abc" : 46,
"qwe" : "Nothing special",
"arrayExample" : [{"var1": 098, "var9" : "string here"}]
},

11: {d: 11, e: [{f: 12, g: "FF"}, {f: 13, g: "GG"}                  ]},
12: {d: 14, e: [{f: 15, g: "HH"}, {f: 16, g: "II"}, {f: 17, g: "JJ"}]},
13: {d: 18, e: [{g: "KK", f: 19}                                    ]},
14: {d: "", e: [{f: 20, g: "LL"}                                    ]},
15: {d: 21, e: [{f: 22, g: 23  }                                    ]},
16: {d: 24, e: [{f: 25, h: "MM"}                                    ]},
17: {d: 26, e: [{f: 27, g: "MM", h: 28}                             ]},
};
const compare = (obj1, obj2) => {
let similar = true;
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
if (obj1Keys.length !== obj2Keys.length) {
similar = false;
} else {
obj1Keys.forEach(key => {
const val1 = obj1[key], val2 = obj2[key];
if (Array.isArray(val1) === true) {
if (Array.isArray(val2) === false) {
similar = false;
} else {
const allSubObjs = [].concat(
Object.keys(val1).map(subKey => val1[subKey]),
Object.keys(val2).map(subKey => val2[subKey])
);
allSubObjs.splice(1).forEach(subObj => {
const recursiveCheck = compare(allSubObjs[0], subObj);
if (recursiveCheck === false) similar = false;
});
}
} else if (typeof val1 !== typeof val2) similar = false;
});
}
return similar;
};
const check = (a, b) => {
console.log(`Test objects ${a} and ${b} are similar? ${compare(tests[a], tests[b])}`);
};
check(1, 2);
check(1, 3);
check(2, 3);
check(11, 12);
check(11, 13);
check(11, 14);
check(11, 15);
check(11, 16);
check(11, 17);

最新更新