如何有选择地合并/更新/忽略两个对象lodash?



我们有两个相同结构的对象,我们希望根据元素名有选择地组合值。有些元素我们希望接受更新值并覆盖,有些元素我们希望忽略更新,还有一些元素是数组,我们希望将它们组合为一个并集。

例如,对于这两个对象…

var server = {
'title': 'string',
'systems': [3,4,5],
'views': 1000,
'authors': ['fred','bill']
};
var update = {
'title': 'new string',
'systems': [5],
'views': 900,
'authors': ['fred','jim']
};

我们要替换title,替换systems,忽略views,并并authors。生成这个对象:

var result = {
'title': 'new string',            // value repaced
'systems': [5],                   // array wholly replaced
'views': 1000,                    // update value ignored
'authors': ['fred','bill','jim']  // update unioned with server
};

我们已经尝试了_.merge_.assign,但它们给出了错误的结果(例如systems变成[5,4,5]),也没有提供忽略特定元素更新的选项(例如视图)

将来可能会添加更多的元素(在代码的其他地方),所以我们不想自定义代码的组合,而是依赖于默认的_.assign_.merge类行为的未知元素。

是否有一个lodash函数可以处理这个?

我不知道是否可以使用lodash,但这里有一个普通的javascript函数可以帮助你做到这一点:

const server = {
'title': 'string',
'systems': [3,4,5],
'views': 1000,
'authors': ['fred','bill']
};
const update = {
'title': 'new string',
'systems': [5],
'views': 900,
'authors': ['fred','jim']
};
const merge = (source, update, actions) => Object.keys(source).reduce((result, k) => {
if (actions.replace.includes(k)) {
result[k] = update[k];
} else if (actions.ignore.includes(k)) {
result[k] = source[k];
} else if (actions.union.includes(k)) {
result[k] = [...new Set([...source[k], ...update[k]])];
}
return result;
}, {});
console.log(merge(server, update, {replace: ['title', 'systems'], ignore: ['views'], union: ['authors']}));

其中actions是类型为

的对象
{replace: [<properties to replace>], ignore: [<properties to ignore>], union: [<properties to union>]}

最新更新