如何比较嵌套对象/数组结构中的特定键值?
How does one compare specific key-values within a nested object / array structure?
我有两个数组如下
array1 = {name:"John",surname:"doe",reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}],id:"12364",weight:"50",Oid:"456978",code:"12"}
array2 = {name:"John",surname:"doe",reference:[{name:"jane",surname:"smith,array:[{name:"test",surname:"test",position:12}]"},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}],id:"4589632",weight:50,policy:"745896",result:"test",documents:"no",launch:"no"}
如您所见,我的两个数组长度都不匹配,所以我无法比较它们。
我只想比较数组 1 和数组 2 中的某些对象。
例如只有我需要的对象
array1
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:"50"
array 2
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:50
我只想比较上面的对象键值所以上面会 return true
如果我有
array1
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:"12"
array 2
name:"John"
surname:"Petter"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"t2",position:12}]},{name:"kate",surname:"Knight",array:[{name:"test",surname:"test",position:14}]}]
weight:50
以上是错误的。
我怎样才能做到这一点?我怎样才能 filter/loop 通过它们只比较上面提到的值。
您可以创建一个函数来进行检查。
备注:
- 我们使用
==
进行比较,因为在您的示例中 weight: 50
等于 weight: '50'
(字符串和数字)。
- 该函数还比较内部数组
reference
使用相同的键进行比较。
function compareObjects(obj1, obj2, keysToCompare) {
return keysToCompare.every(x => obj1[x] instanceof Array ?
obj1[x].every((y, yi) => compareObjects(y, obj2[x][yi], Object.keys(y))) :
obj1[x] == obj2[x]);
}
// Nothing is different - should work
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
},
{
name: 'kate',
surname: 'post'
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// One key is different - should fail
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
// This value is different
surname: 'FOOL',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// One key is different - should fail
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
// This value is different
surname: 'FOOL',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// Position is different - should work
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
},
{
name: 'kate',
surname: 'post',
position: 10,
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
}, {
name: 'kate',
surname: 'post',
position: 15,
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// Everything is same - should work (including position)
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
},
{
name: 'kate',
surname: 'post',
position: 10,
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
}, {
name: 'kate',
surname: 'post',
position: 10,
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
对于给定的 scenario/example 一个可靠甚至推荐的方法是提供自定义 stringify 函数,该函数 unifies/normalizes 任何提供的对象结构(它们可能不同在对象之间)并清理任何对象的值类型(例如,在 OP 提供的对象示例中有所不同),然后 return 代表这个对象的字符串。
以这种方式处理的对象可以安全地相互比较...
const objA = {
name: "John",
surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]
}, {
name: "kate", surname:"post", array:[
{ name: "test", surname: "test", position: 12 }
]
}],
id: "12364",
weight: "50",
Oid: "456978",
code: "12",
};
const objB = {
reference: [{
surname:"post", name: "kate", array:[
{ name: "test", surname: "test", position: 12 }
]
}, {
array: [
{ name: "test", surname: "test", position: 12 }
],
name: "jane",
surname: "smith",
}],
surname: "doe",
name: "John",
id: "4589632",
weight: 50,
policy: "745896",
result: "test",
documents: "no",
launch: "no",
};
const objC = {
name: "John", surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]}, {
name: "kate", surname:"post", array:[
{ name: "test", surname: "test", position: 12 }
]
}],
weight: "60",
};
const objD = {
name: "John", surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]}, {
name: "kate", surname:"post", array:[
{ name: "test", surname:"test", position: 24 }
]
}],
weight: "60",
};
const orderByName = (a, b) =>
a.surname.localeCompare(b.surname) || a.name.localeCompare(b.name);
function normalizeItemReference(arr) {
return arr
// assure a certain order.
.sort(orderByName)
// assure identical structure.
.map(({ name, surname, array }) =>
({
name,
surname,
array: array
// assure a certain order.
.sort(orderByName)
// assure identical structure and value type.
.map(({ name, surname, position }) =>
({ name, surname, position: Number(position) })
)
})
);
}
function stringifyItem(obj) {
const { name, surname, weight, reference } = obj;
return JSON.stringify({
// assure identical structure and value types.
name,
surname,
weight: Number(weight),
reference: normalizeItemReference(reference)
});
}
console.log(
'(stringifyItem(objA) === stringifyItem(objB)) ?',
(stringifyItem(objA) === stringifyItem(objB))
);
console.log(
'(stringifyItem(objA) === stringifyItem(objC)) ?',
(stringifyItem(objA) === stringifyItem(objC))
);
console.log(
'(stringifyItem(objC) === stringifyItem(objD)) ?',
(stringifyItem(objC) === stringifyItem(objD))
);
console.log(
'stringifyItem(objA) ...',
stringifyItem(objA)
);
console.log(
'stringifyItem(objB) ...',
stringifyItem(objB)
);
console.log(
'stringifyItem(objC) ...',
stringifyItem(objC)
);
console.log(
'stringifyItem(objD) ...',
stringifyItem(objD)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我有两个数组如下
array1 = {name:"John",surname:"doe",reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}],id:"12364",weight:"50",Oid:"456978",code:"12"}
array2 = {name:"John",surname:"doe",reference:[{name:"jane",surname:"smith,array:[{name:"test",surname:"test",position:12}]"},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}],id:"4589632",weight:50,policy:"745896",result:"test",documents:"no",launch:"no"}
如您所见,我的两个数组长度都不匹配,所以我无法比较它们。
我只想比较数组 1 和数组 2 中的某些对象。 例如只有我需要的对象
array1
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:"50"
array 2
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:50
我只想比较上面的对象键值所以上面会 return true
如果我有
array1
name:"John"
surname:"doe"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"test",position:12}]},{name:"kate",surname:"post",array:[{name:"test",surname:"test",position:12}]}]
weight:"12"
array 2
name:"John"
surname:"Petter"
reference:[{name:"jane",surname:"smith",array:[{name:"test",surname:"t2",position:12}]},{name:"kate",surname:"Knight",array:[{name:"test",surname:"test",position:14}]}]
weight:50
以上是错误的。
我怎样才能做到这一点?我怎样才能 filter/loop 通过它们只比较上面提到的值。
您可以创建一个函数来进行检查。
备注:
- 我们使用
==
进行比较,因为在您的示例中weight: 50
等于weight: '50'
(字符串和数字)。 - 该函数还比较内部数组
reference
使用相同的键进行比较。
function compareObjects(obj1, obj2, keysToCompare) {
return keysToCompare.every(x => obj1[x] instanceof Array ?
obj1[x].every((y, yi) => compareObjects(y, obj2[x][yi], Object.keys(y))) :
obj1[x] == obj2[x]);
}
// Nothing is different - should work
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
},
{
name: 'kate',
surname: 'post'
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// One key is different - should fail
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
// This value is different
surname: 'FOOL',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// One key is different - should fail
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
}, {
name: 'kate',
surname: 'post',
}],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
// This value is different
surname: 'FOOL',
}, {
name: 'kate',
surname: 'post',
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// Position is different - should work
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
},
{
name: 'kate',
surname: 'post',
position: 10,
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
}, {
name: 'kate',
surname: 'post',
position: 15,
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
// Everything is same - should work (including position)
console.log(compareObjects({
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
},
{
name: 'kate',
surname: 'post',
position: 10,
},
],
id: '12364',
weight: '50',
Oid: '456978',
code: '12',
}, {
name: 'John',
surname: 'doe',
reference: [{
name: 'jane',
surname: 'smith',
position: 10,
}, {
name: 'kate',
surname: 'post',
position: 10,
}],
id: '4589632',
weight: 50,
policy: '745896',
result: 'test',
documents: 'no',
launch: 'no',
}, [
'name',
'surname',
'reference',
'weight',
]));
对于给定的 scenario/example 一个可靠甚至推荐的方法是提供自定义 stringify 函数,该函数 unifies/normalizes 任何提供的对象结构(它们可能不同在对象之间)并清理任何对象的值类型(例如,在 OP 提供的对象示例中有所不同),然后 return 代表这个对象的字符串。
以这种方式处理的对象可以安全地相互比较...
const objA = {
name: "John",
surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]
}, {
name: "kate", surname:"post", array:[
{ name: "test", surname: "test", position: 12 }
]
}],
id: "12364",
weight: "50",
Oid: "456978",
code: "12",
};
const objB = {
reference: [{
surname:"post", name: "kate", array:[
{ name: "test", surname: "test", position: 12 }
]
}, {
array: [
{ name: "test", surname: "test", position: 12 }
],
name: "jane",
surname: "smith",
}],
surname: "doe",
name: "John",
id: "4589632",
weight: 50,
policy: "745896",
result: "test",
documents: "no",
launch: "no",
};
const objC = {
name: "John", surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]}, {
name: "kate", surname:"post", array:[
{ name: "test", surname: "test", position: 12 }
]
}],
weight: "60",
};
const objD = {
name: "John", surname: "doe",
reference: [{
name: "jane", surname: "smith", array: [
{ position: 12, surname: "test", name: "test" }
]}, {
name: "kate", surname:"post", array:[
{ name: "test", surname:"test", position: 24 }
]
}],
weight: "60",
};
const orderByName = (a, b) =>
a.surname.localeCompare(b.surname) || a.name.localeCompare(b.name);
function normalizeItemReference(arr) {
return arr
// assure a certain order.
.sort(orderByName)
// assure identical structure.
.map(({ name, surname, array }) =>
({
name,
surname,
array: array
// assure a certain order.
.sort(orderByName)
// assure identical structure and value type.
.map(({ name, surname, position }) =>
({ name, surname, position: Number(position) })
)
})
);
}
function stringifyItem(obj) {
const { name, surname, weight, reference } = obj;
return JSON.stringify({
// assure identical structure and value types.
name,
surname,
weight: Number(weight),
reference: normalizeItemReference(reference)
});
}
console.log(
'(stringifyItem(objA) === stringifyItem(objB)) ?',
(stringifyItem(objA) === stringifyItem(objB))
);
console.log(
'(stringifyItem(objA) === stringifyItem(objC)) ?',
(stringifyItem(objA) === stringifyItem(objC))
);
console.log(
'(stringifyItem(objC) === stringifyItem(objD)) ?',
(stringifyItem(objC) === stringifyItem(objD))
);
console.log(
'stringifyItem(objA) ...',
stringifyItem(objA)
);
console.log(
'stringifyItem(objB) ...',
stringifyItem(objB)
);
console.log(
'stringifyItem(objC) ...',
stringifyItem(objC)
);
console.log(
'stringifyItem(objD) ...',
stringifyItem(objD)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }