首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何比较两个嵌套对象,减去差异&返回相等的值?

如何比较两个嵌套对象,减去差异&返回相等的值?
EN

Stack Overflow用户
提问于 2021-07-13 15:14:49
回答 1查看 267关注 0票数 1

我有以下两个变量。

代码语言:javascript
复制
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,
              },
            ],
          },
        ],
      },
  };

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

代码语言:javascript
复制
  students: {
    grade: [
      {
        subject: "Math3",
        name: "jack",
        diff: 20
      },
    ],
    class: [
      {
        className: "math3",
        diff: 10,
        requirment: [
          {
            subject: "math1",
            diff: 15,
          },
          {
              subject: "math2",
              diff: 30,
          },
        ],
      },
    ],
  },
};

到目前为止密码。我得到的是价值,但不是我想要的方式。还有更清洁的方法吗。

代码语言:javascript
复制
  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)

任何建议都是非常感谢的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-20 18:45:31

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

代码语言:javascript
复制
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属性,但是在某些情况下,对象有两个数字属性,因此它将被覆盖,我保留了原始属性名。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68365128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档