我正在努力学习Lodash,因为我觉得它对我目前的项目有很大的帮助。但是,我有一个问题,我无法弄清楚如何解决,而且,因为我是一个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);
}
});
});
});
});
});
});
任何想法,帮助,想法等?
谢谢!
答案 0 :(得分:4)
我使用基于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库的功能。
答案 1 :(得分:1)
你可以做的是构建一个只包含你想要保留的东西的小对象,让它称之为diffObject
,所以你只需要这样做:
// Puts the diff back into the original object
_.merge( originalObject, diffObject );
现在要构建这样的diff对象,你可能仍然需要浏览所有对象,或者有一些聪明的递归构建函数来跟踪它经历的路径和所有对象。