如何比较 2 个嵌套对象,减去差值并返回相等值?



我有以下两个变量。

const val1 = {
students: {
grade: [
{
subject: "Math3",
name: "jack",
mark: 60,
attendance: 90,
abscent: 2,
},
],
class: [
{
className: "math3",
students: 50,
absenteeism: 10,
requirment: [
{
subject: "math1",
mark: 60,
pass: 51,
},
{
subject: "math2",
mark: 60,
pass: 51,
},
],
},
],
},
};

const val2 = {
students: {
grade: [
{
subject: "Math3",
name: "jack",
mark: 80
},
],
class: [
{
className: "math3",
students: 40,
absenteeism: 10,
requirment: [
{
subject: "math1",
mark: 75,
pass: 51,
},
{
subject: "math2",
mark: 90,
pass: 51,
},
],
},
],
},
};

我试图通过返回键和值来获得以下结果,如果它们相同,&如果密钥是一个数字,则返回该数字的差值&如果项目不存在,请跳过。像这样。

students: {
grade: [
{
subject: "Math3",
name: "jack",
diff: 20
},
],
class: [
{
className: "math3",
diff: 10,
requirment: [
{
subject: "math1",
diff: 15,
},
{
subject: "math2",
diff: 30,
},
],
},
],
},
};

到目前为止的代码。我得到了价值,但不是我想要的方式。还有,有没有更干净的方式。

const changeTable = (table1, table2) => {
const result = {};
result["students"] = {};
let file1= table1.students
let file2=table2.students

for (let x in file1) {
if (file2[x]) {
result.students[x] =file1[x]
.map((y) => file2[x]
.map((z)=> Object.keys(y)
.map((key)=> {

if (y[key] === z[key]) {
return {[key]:y[key]}
}
if (y[key] !== z[key]) {
if (typeof y[key] === "number") {
const res= Number(z[key])-Number(y[key])
if (!isNaN(res)) {
return {[key]:res}
}
}
}
}

).filter(i =>i)))
}
}
return result
};

changeTable(val1, val2)

如有任何建议,不胜感激。

我试图尽可能接近您的预期输出。一般来说,这不适合像map这样的数组方法,因为这里真正需要的是对象的递归遍历。我在代码中添加了注释,以显示它在做什么,以防出现不太正确的情况。

const val1 = {
"students": {
"grade": [
{
"subject": "Math3",
"name": "jack",
"mark": 60,
"attendance": 90,
"abscent": 2
}
],
"class": [
{
"className": "math3",
"students": 50,
"absenteeism": 10,
"requirment": [
{
"subject": "math1",
"mark": 60,
"pass": 51
},
{
"subject": "math2",
"mark": 60,
"pass": 51
}
]
}
]
}
}
const val2 = {
"students": {
"grade": [
{
"subject": "Math3",
"name": "jack",
"mark": 80
}
],
"class": [
{
"className": "math3",
"students": 40,
"absenteeism": 10,
"requirment": [
{
"subject": "math1",
"mark": 75,
"pass": 51
},
{
"subject": "math2",
"mark": 90,
"pass": 51
}
]
}
]
}
}
function diffObject(obj1, obj2) {
let result = {}
for (let key in obj1) {
// ignore properties not present in both objects
if (!(key in obj2)) continue
// ignore not same type, such as a number and string
if (typeof obj1[key] !== typeof obj2[key]) continue
// when both are number, set the property to the difference of the two
if (typeof obj1[key] === 'number') {
// only use different numbers
if (obj1[key] !== obj2[key]) {
result[key] = obj2[key] - obj1[key]
// in case you really wanted the "diff" property
// result.diff = obj2[key] - obj1[key]
}
}
// recursively iterate over each member of array
else if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
result[key] = obj1[key].map((item, index) => diffObject(item, obj2[key][index]))
}
// recursively iterate objects
else if (typeof obj1[key] === 'object' && obj1[key]) {
result[key] = diffObject(obj1[key], obj2[key])
}
// copy equal data
else if (obj1[key] === obj2[key]) {
result[key] = obj1[key]
}
// anything else is ignored
}
return result
}
console.log(diffObject(val1, val2))

有些边缘情况无法解决,例如递归结构或非纯对象。

此外,在您想要的输出中,您可以继续使用diff属性,但在某些情况下,对象有两个数字属性,因此它会被覆盖,我保留了原始属性名称。

最新更新