繁体   English   中英

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

[英]How to use Lodash to compare and find difference for two complex objects?

我现在正在尝试学习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”集合,然后遍历整个原始对象,找到与之完全匹配的“ widget” ,并使用复制对象中的值更新匹配的小部件的“ widgetName”和“ widgetParameters”。

我已经使用蛮力方法进行了很多努力(请参阅下文),但是我认为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的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库功能的优雅而简单的方法。

您可以做的是构建一个较小的对象,该对象仅包含要保留的内容,我们将其diffObject ,因此您只需要执行以下操作:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM