检查两个对象之间的键是否匹配的最简单方法是什么?
Whats the easiest way to check if keys match between two objects?
假设您有两个嵌套相当多的对象...
const objA = {
one: {
a: 10,
b: 'string1',
c: {
d: 10
}
},
two : 'string1'
}
const objB = {
one: {
a: 20,
b: 'string2',
c: {
d: 20
}
},
two : 'string2'
}
有没有一种简单的方法来检查它们之间的所有键是否匹配?
*匹配:两个对象在同一个嵌套位置有相同的键,没有多余的键,所以objA
和objB
匹配
在普通的 Javascript 中,您可以获取键,比较长度并迭代键并检查值是否为对象。
function compareKeys(a, b) {
var keysA = Object.keys(a),
keysB = Object.keys(b);
return keysA.length === keysB.length
&& keysA.every(k => b.hasOwnProperty(k) && (
a[k] && typeof a[k] === 'object' ||
b[k] && typeof b[k] === 'object'
? compareKeys(a[k], b[k])
: true));
}
const
objA = { one: { a: 10, b: 'string1', c: { d: 10 } }, two : 'string1' },
objB = { one: { a: 20, b: 'string2', c: { d: 20 } }, two : 'string2' },
objC = { one: { a: 20, b: 'string2', c: { d: 20, e: false } }, two : 'string2' };
console.log(compareKeys(objA, objB));
console.log(compareKeys(objA, objC));
console.log(compareKeys({ a: {} }, { a: "test" }));
console.log(compareKeys({ a: "test" }, { a: {} }));
console.log(compareKeys({ a: { b: "new str" } }, { a: "test" }));
我建议从 lodash、https://lodash.com/docs/4.17.11#isEqual
查看 isEqual 的实现
这与 Nina Scholz 的回答非常相似,只是想法上的差异足以使其成为一个有趣的替代方案:
const matchingStructure = (a, b, ak = Object.keys(a), bk = Object.keys(b)) =>
!(typeof a == 'object' && typeof b == 'object') ||
( ak.length === bk.length &&
ak.every(k => k in b) &&
ak.every(k => matchingStructure(a[k], b[k]))
)
const objA = {one: {a: 10, b: "string1", c: {d: 10}}, two: "string1"}
const objB = {one: {a: 20, b: "string2", c: {d: 20}}, two: "string2"}
const objC = {one: {a: 30, b: "string3", c: {d: 30}, e: true}, two: "string3"}
console.log(matchingStructure(objA, objB))
console.log(matchingStructure(objA, objC))
它很可能在循环结构上失败。我还没想好。
我认为下面的代码应该广泛涵盖解决方案的所有类型的对象。
const doAllKeysMatch = (obj1, obj2) => {
if (typeof obj1 != 'object' && typeof obj1 != 'object') {
return true;
}
if (typeof obj1 == 'object' && typeof obj1 == 'object') {
// if both are object types compare all keys
let obj1Keys = Object.keys(obj1);
let obj2Keys = Object.keys(obj2);
return (obj1Keys.length == obj2Keys.length) && obj1Keys.every(key => obj2Keys.includes(key) && doAllKeysMatch(obj1[key], obj2[key]))
}
/*
if only one is of object type check if it doesnt have any keys.
if empty object is there then return true which means "abc" and {} have same keys
*/
if ((typeof obj1 == 'object') && (Object.keys(obj1).length < 1)) {
return true
}
return Object.keys(obj2).length < 1;
}
console.log(doAllKeysMatch("abc", "dfg")) // true
console.log(doAllKeysMatch("abc", {})) // true
console.log(doAllKeysMatch({a: "test"}, {a: {}})) // true
console.log(
doAllKeysMatch(
{
a: 10,
b: 'string1',
c: { d: 10 },
two : 'string1'
},
{
a: 10,
b: 'string1',
c: { d: false },
two : 'string2'
}
)) // true
假设您有两个嵌套相当多的对象...
const objA = {
one: {
a: 10,
b: 'string1',
c: {
d: 10
}
},
two : 'string1'
}
const objB = {
one: {
a: 20,
b: 'string2',
c: {
d: 20
}
},
two : 'string2'
}
有没有一种简单的方法来检查它们之间的所有键是否匹配?
*匹配:两个对象在同一个嵌套位置有相同的键,没有多余的键,所以objA
和objB
匹配
在普通的 Javascript 中,您可以获取键,比较长度并迭代键并检查值是否为对象。
function compareKeys(a, b) {
var keysA = Object.keys(a),
keysB = Object.keys(b);
return keysA.length === keysB.length
&& keysA.every(k => b.hasOwnProperty(k) && (
a[k] && typeof a[k] === 'object' ||
b[k] && typeof b[k] === 'object'
? compareKeys(a[k], b[k])
: true));
}
const
objA = { one: { a: 10, b: 'string1', c: { d: 10 } }, two : 'string1' },
objB = { one: { a: 20, b: 'string2', c: { d: 20 } }, two : 'string2' },
objC = { one: { a: 20, b: 'string2', c: { d: 20, e: false } }, two : 'string2' };
console.log(compareKeys(objA, objB));
console.log(compareKeys(objA, objC));
console.log(compareKeys({ a: {} }, { a: "test" }));
console.log(compareKeys({ a: "test" }, { a: {} }));
console.log(compareKeys({ a: { b: "new str" } }, { a: "test" }));
我建议从 lodash、https://lodash.com/docs/4.17.11#isEqual
查看 isEqual 的实现这与 Nina Scholz 的回答非常相似,只是想法上的差异足以使其成为一个有趣的替代方案:
const matchingStructure = (a, b, ak = Object.keys(a), bk = Object.keys(b)) =>
!(typeof a == 'object' && typeof b == 'object') ||
( ak.length === bk.length &&
ak.every(k => k in b) &&
ak.every(k => matchingStructure(a[k], b[k]))
)
const objA = {one: {a: 10, b: "string1", c: {d: 10}}, two: "string1"}
const objB = {one: {a: 20, b: "string2", c: {d: 20}}, two: "string2"}
const objC = {one: {a: 30, b: "string3", c: {d: 30}, e: true}, two: "string3"}
console.log(matchingStructure(objA, objB))
console.log(matchingStructure(objA, objC))
它很可能在循环结构上失败。我还没想好。
我认为下面的代码应该广泛涵盖解决方案的所有类型的对象。
const doAllKeysMatch = (obj1, obj2) => {
if (typeof obj1 != 'object' && typeof obj1 != 'object') {
return true;
}
if (typeof obj1 == 'object' && typeof obj1 == 'object') {
// if both are object types compare all keys
let obj1Keys = Object.keys(obj1);
let obj2Keys = Object.keys(obj2);
return (obj1Keys.length == obj2Keys.length) && obj1Keys.every(key => obj2Keys.includes(key) && doAllKeysMatch(obj1[key], obj2[key]))
}
/*
if only one is of object type check if it doesnt have any keys.
if empty object is there then return true which means "abc" and {} have same keys
*/
if ((typeof obj1 == 'object') && (Object.keys(obj1).length < 1)) {
return true
}
return Object.keys(obj2).length < 1;
}
console.log(doAllKeysMatch("abc", "dfg")) // true
console.log(doAllKeysMatch("abc", {})) // true
console.log(doAllKeysMatch({a: "test"}, {a: {}})) // true
console.log(
doAllKeysMatch(
{
a: 10,
b: 'string1',
c: { d: 10 },
two : 'string1'
},
{
a: 10,
b: 'string1',
c: { d: false },
two : 'string2'
}
)) // true