javascript - 比较对象的两个深层嵌套对象并仅返回 javascript/lodash 中的差异

标签 javascript node.js lodash javascript-objects

我有 2 个深层嵌套的对象。一个是“基础”对象,另一个是修改后的对象。

我本质上是想从修改的对象中“删除”基础对象并返回一个仅包含不同数据的对象。这是一个例子:

基础对象:

baseObj : {
    image: {
        width: '100%',
        paddingTop: '0px',
        paddingRight: '0px',
        paddingBottom: '0px',
        paddingLeft: '0px'
    },
    wrap: {
        marginTop: '0px',
        marginRight: '0px',
        marginBottom: '0px',
        marginLeft: '0px'
    }
}

具有修改数据的对象

mergedObject : {
    image: {
        width: '100%',  
        paddingTop: '0px',
        paddingRight: '24px', // modified value
        paddingBottom: '24px', // modified value
        paddingLeft: '0px'
    },
    wrap: {
        height: '100px', // new value
        marginTop: '24px', // modified value
        marginRight: '0px',
        marginBottom: '0px',
        marginLeft: '24px' // modified value
    }
}

我想要一个像这样返回的对象:

diffObject : {
    image: {
        paddingRight: '24px',
        paddingBottom: '24px',
    },
    wrap: {
        height: '100px',
        marginTop: '24px',
        marginLeft: '24px'
    }
}

嵌套可能会更深一点,因此它需要是动态的。有没有办法使用 lodash 或其他库?

最佳答案

要解决这个问题,我们必须:

  • 创建一个递归遍历对象中每个 Node 的函数。我们可以通过使用reduce来实现这一点遍历source对象时的函数。
  • reduce 回调函数将首先检查source 值或其other 值对应部分是否都是对象。如果是,我们将使用这些值作为参数来递归地获取这两个对象的差异。否则,如果它们不同,我们将分配other值的结果值。
  • 最后,reduce 函数接受第三个参数,该参数用作 reduce 函数累加的初始值。我们将 other 对象中的键值分配给第三个参数,但在 source 对象中找不到这些键值。这是从 other 对象向结果对象获取新引入的值的最简单方法。
<小时/>
function differenceObjectDeep(source, other) {
  return _.reduce(source, function(result, value, key) {
    if (_.isObject(value) && _.isObject(other[key])) {
      result[key] = differenceObjectDeep(
        value,
        other[key]
      );
    } else if (!_.isEqual(value, other[key])) {
      result[key] = other[key];
    }
    return result;
  }, _.omit(other, _.keys(source)));
}

data.diffObject = differenceObjectDeep(
  data.baseObj,
  data.mergedObject
);

var data = {
  baseObj: {
    image: {
      width: '100%',
      paddingTop: '0px',
      paddingRight: '0px',
      paddingBottom: '0px',
      paddingLeft: '0px'
    },
    wrap: {
      marginTop: '0px',
      marginRight: '0px',
      marginBottom: '0px',
      marginLeft: '0px'
    }
  },
  mergedObject: {
    image: {
      width: '100%',
      paddingTop: '0px',
      paddingRight: '24px', // modified value
      paddingBottom: '24px', // modified value
      paddingLeft: '0px'
    },
    wrap: {
      height: '100px', // new value
      marginTop: '24px', // modified value
      marginRight: '0px',
      marginBottom: '0px',
      marginLeft: '24px' // modified value
    }
  }
};

function differenceObjectDeep(source, other) {
  return _.reduce(source, function(result, value, key) {
    if (_.isObject(value) && _.isObject(other[key])) {
      result[key] = differenceObjectDeep(
        value,
        other[key]
      );
    } else if (!_.isEqual(value, other[key])) {
      result[key] = other[key];
    }
    return result;
  }, _.omit(other, _.keys(source)));
}

data.diffObject = differenceObjectDeep(
  data.baseObj,
  data.mergedObject
);

console.log(data.diffObject);
body>div {
  min-height: 100%;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

关于javascript - 比较对象的两个深层嵌套对象并仅返回 javascript/lodash 中的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42281957/

相关文章:

javascript - Array.prototype.splice() 在迭代时不删除对象

node.js - Sequelize 选择并包含另一个表别名

javascript - Jquery 事件不会在手动添加的元素上触发

javascript - 尝试使用 jQuery 检索部分 URL;它有效,但未返回字符串

javascript - HTML5/JavaScript "Save As"文件下载对话框

node.js - 如何获取 json 对象数组而不是 Mongoose 文档

javascript - Lodash groupBy 与时刻

angular - 找不到模块 : Error: Can't resolve 'lodash-es'

javascript - Lodash/Javascript 比较数组或对象,如果任何 Prop 匹配则失败

javascript - 如何在 node js 中生成和验证 JWE?