Javascript 如何使用Lodash来比较和发现两个复杂对象的差异?

Javascript 如何使用Lodash来比较和发现两个复杂对象的差异?,javascript,angularjs,underscore.js,lodash,Javascript,Angularjs,Underscore.js,Lodash,我现在正在努力学习Lodash,因为我认为它对我目前的项目有很大帮助。然而,我有一个问题,我不知道如何解决,而且,因为我是一个洛达斯菜鸟,我想我应该发布一些东西,看看我是否可以得到一些指导 我有两个复杂的对象(见下面的结构)——使用angular.copy(原件,副本)(我的应用程序显然是angular应用程序) 在副本之后,两个 original and copy = { name: 'name', date: 'date', rows: [ // array of

我现在正在努力学习Lodash,因为我认为它对我目前的项目有很大帮助。然而,我有一个问题,我不知道如何解决,而且,因为我是一个洛达斯菜鸟,我想我应该发布一些东西,看看我是否可以得到一些指导

我有两个复杂的对象(见下面的结构)——使用angular.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);
                        }

                    });
                });
            });

        });
    });
});
有什么想法、帮助、想法等吗


谢谢

您可以构建一个较小的对象,它只包含您想要保留的东西,我们称之为
diffObject
,因此您只需要执行以下操作:

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

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

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

// 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库的功能。

所以只有叶节点可以修改?