比较JavaScript中的嵌套对象并返回键相等 [英] Compare nested objects in JavaScript and return keys equality

查看:54
本文介绍了比较JavaScript中的嵌套对象并返回键相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个嵌套对象 obj1 obj2 我希望比较它们并递归返回一个对象对于每个嵌套键都有一个类似于等式的布尔标志

I have two nested objects obj1 and obj2 and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag

所以对于给定的 obj1 喜欢

obj1 = {
  prop1: 1,
  prop2: "foo",
  prop3: {
    prop4: 2,
    prop5: "bar" 
  }
}

obj2 喜欢

obj2 = {
      prop1: 3,
      prop2: "foo",
      prop3: {
        prop4: 2,
        prop5: "foobar" 
      },
      prop6: "new"
    }

它应该返回

equality = {
     prop1: false,
     prop2: true,
     prop3 : {
       prop4: true,
       prop5: false
     },
     prop6: false
   }

如果某个对象有一个新属性,例如 obj2 .prop6 ,那么相等将是 equality.prop6 = false

If an object has a new property, like obj2.prop6, then the equality will be equality.prop6 = false.

For非嵌套对象一个简单的密钥比较解决方案就在这里获取javascript中两个对象之间差异的属性
虽然递归比较嵌套对象,但它显示在这里 JavaScript:递归深度比较:对象和属性

For non-nested object a simple keys comparison solutions is here Get the property of the difference between two objects in javascript While to recursively compare nested objects it is showed here JavaScript: Deep comparison recursively: Objects and properties

推荐答案

您可以使用 reduce 来构建新对象,并使用另一个获取方法来获取嵌套道具来自 string 的其他对象,并将其与第一个对象中的当前道具值进行比较。

You could use reduce to build new object and another get method to get nested props from other object by string and compare it to current prop value in first object.

const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }

function get(obj, path) {
  return path.split('.').reduce((r, e) => {
    if (!r) return r
    else return r[e] || undefined
  }, obj)
}

function compare(a, b, prev = "") {
  return Object.keys(a).reduce((r, e) => {
    const path = prev + (prev ? '.' + e : e);
    const value = a[e] === get(b, path);
    r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
    return r;
  }, {})
}

const result = compare(obj1, obj2);
console.log(result)

要比较两个对象的所有属性,您可以创建将由两个对象执行循环的额外函数。

To compare all properties of both objects you could create extra function that will perform loop by both objects.

const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}

function get(obj, path) {
  return path.split('.').reduce((r, e) => {
    if (!r) return r;
    else return r[e] || undefined;
  }, obj);
}

function isEmpty(o) {
  if (typeof o !== 'object') return true;
  else return !Object.keys(o).length;
}

function build(a, b, o = null, prev = '') {
  return Object.keys(a).reduce(
    (r, e) => {
      const path = prev + (prev ? '.' + e : e);
      const bObj = get(b, path);
      const value = a[e] === bObj;

      if (typeof a[e] === 'object') {
        if (isEmpty(a[e]) && isEmpty(bObj)) {
          if (e in r) r[e] = r[e];
          else r[e] = true;
        } else if (!bObj && isEmpty(a[e])) {
          r[e] = value;
        } else {
          r[e] = build(a[e], b, r[e], path);
        }
      } else {
        r[e] = value;
      }
      return r;
    },
    o ? o : {}
  );
}

function compare(a, b) {
  const o = build(a, b);
  return build(b, a, o);
}

const result = compare(obj1, obj2);
console.log(result)

这篇关于比较JavaScript中的嵌套对象并返回键相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆