【问题标题】:How to use Lodash to compare and find difference for two complex objects?如何使用 Lodash 比较两个复杂对象并找出差异?
【发布时间】:2015-06-23 14:18:22
【问题描述】:

我现在正在尝试学习 Lodash,因为我认为它对我当前的项目有很大帮助。但是,我有一个不知道如何解决的问题,而且,由于我是 Lodash 新手,所以我想我会发布一些东西,看看是否可以得到一些指导。

我有两个复杂的对象(参见下面的结构)——使用 angular.copy(original, copy) 制作(我的应用显然是一个 Angular 应用)。

复制后,两个

original and copy =
{
    name: 'name',
    date: 'date',
    rows: [  // array of objects
        {
            // this is row 1
            columns: [  // array of objects
                {
                    // this is column 1
                    widgets: [  // array of objects
                        {
                            // this is 1 widget in this column
                            createdDate: 'createdDate1',
                            widgetName: 'widgetName1',
                            widgetParameters: [  // array of objects
                                { parameterName: 'parameterName1', parameterValue: 'parameterValue1' },
                                { parameterName: 'parameterName2', parameterValue: 'parameterValue2' },
                                { parameterName: 'parameterName3', parameterValue: 'parameterValue3' }
                            ]
                        }
                    ]
                },
                {
                    // this is column 2
                    widgets: [
                        {
                            // this is 1 widget in this column
                            createdDate: 'createdDate2',
                            widgetName: 'widgetName2',
                            widgetParameters: [  // array of objects
                                { parameterName: 'parameterName1a', parameterValue: 'parameterValue1a' },
                                { parameterName: 'parameterName2a', parameterValue: 'parameterValue2a' }
                            ]
                        },
                        {
                            // this is 2 widget in this column
                            // ...
                        }
                    ]
                },
                {
                    // this is column 3
                    widgets: [
                        {
                            // this is 1 widget in this column
                            createdDate: 'createdDate3',
                            widgetName: 'widgetName3',
                            widgetParameters: [  // array of objects
                                { parameterName: 'parameterName1b', parameterValue: 'parameterValue1a' }
                            ]
                        },
                        {
                            // this is 2 widget in this column
                            // ...
                        },
                        {
                            // this is 3 widget in this column
                            // ...
                        }
                    ]
                }
            ]  // end columns array
        },
        {
            // this is row 2
            // ... same structure as above with columns, widgets, widgetParameters
        }
    ]  // end rows array
}

在对属性值进行进一步处理和更改后,我现在需要将复制对象中的一些属性(不是全部)重新同步回原始对象。具体来说,我需要遍历整个复制对象,找到所有“小部件”,从小部件中获取“widgetName”值和完整的“widgetParameters”集合,然后遍历整个原始对象,找到完全匹配的“小部件” ,并使用复制对象中的值更新匹配小部件的“widgetName”和“widgetParameters”。

我已经通过大量 forEach'ing(见下文)的蛮力方法让它工作,但我认为在 Lodash 中可能有一种更优雅、更有效的方式来做我想做的事情.

// brute force it
angular.forEach(copy.rows, function (row) {
    angular.forEach(row.columns, function (column) {
        angular.forEach(column.widgets, function (widget) {
            var widgetName = widget.widgetName;
            var createdDate = widget.createdDate;
            var widgetParameters = widget.widgetParameters;

            angular.forEach(original.rows, function (row1) {
                angular.forEach(row1.columns, function (column1) {
                    angular.forEach(column1.widgets, function (widget1) {

                        if ((widgetName === widget1.widgetName) && (createdDate === widget1.createdDate))
                        {
                            widget1.widgetName = widgetName;
                            angular.copy(widgetParameters, widget1.widgetParameters);
                        }

                    });
                });
            });

        });
    });
});

有什么想法、帮助、想法等吗?

谢谢!

【问题讨论】:

  • 所以只能修改叶子节点?

标签: javascript angularjs underscore.js lodash


【解决方案1】:

我在使用基于 JavaScript 的 deep-diff 实用程序方面取得了巨大成功。例如:

// this would be a node.js way to require it, or you could use the DeepDiff object in the browser's global window object
var diff = require('deep-diff').diff;
var differences = diff(original, copy);

如果您想在浏览器级别应用一些更改,您可以迭代更改(差异)并对收到的每个差异执行类似的操作:

DeepDiff.applyChange(original, {}, difference);

我不知道在 Lodash 中没有重新构建 deep-diff 库的功能的优雅而简单的方法。

【讨论】:

    【解决方案2】:

    你可以做的是构建一个只包含你想要保留的东西的小对象,我们称之为diffObject,那么你只需要这样做:

    // Puts the diff back into the original object
    _.merge( originalObject, diffObject );
    

    现在要构造这样的 diff 对象,您可能仍然需要遍历所有对象,或者使用一些巧妙的递归构建函数来跟踪它所经过的路径等等。

    【讨论】:

      猜你喜欢
      • 2011-06-24
      • 2019-07-19
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      相关资源
      最近更新 更多