如何使用Underscore.js合并对象数组

6

我有一个对象数组,像这样:

array1 = [
  {field: 'username', display: 'username', hide: true},
  {field: 'age', display: 'Age', hide: true},
  {field: 'height', display: 'Height', hide: true}
]

然后我有一个array2:

array2 = [
  {field: 'username', display: 'username 123', hide: false},
  {field: 'age', hide: false}
]

我希望通过它们的字段将这两个数组合并,即最终结果应该是:
array3 = [
  {field: 'username', display: 'username 123', hide: false},
  {field: 'age', display: 'Age', hide: false},
  {field: 'height', display: 'Height', hide: true}
]

我尝试了var newObj = _.extend(array1, array2);,但它并没有给我想要的结果。

你正在寻找concat。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat - Brian
@Brian:不,他正在进行某种更新。 - Karoly Horvath
@Karoly Horvath 噢,他想要合并对象和数组。 - Brian
如果array2包含新元素,甚至不清楚顺序是什么...顺序重要吗?如果不重要,使用普通对象(作为字典)。如果重要,有序字典更适合此任务。它有助于查找。 - Karoly Horvath
1个回答

11

没有一个函数可以完成它,因为这是一个相当专业化的操作。然而,它是underscore函数的一个相当简单的组合:

_.values(_.extend(_.indexBy(array1, 'field'), _.indexBy(array2, 'field')))
我们使用indexBy将数组转换为以field值为键的对象,然后使用extend实现我们想要的功能。最后,values将其转换回数组。
请注意,虽然这并不保证顺序,但在当前的_和v8实现中,最终的数组将是来自array1的内容,后跟来自array2中不在array1中的内容,并按照每个数组的原始顺序排序。
还要注意,_.extend函数对第一个参数具有破坏性,而这并不会改变任何数组。
如果您想确保顺序与原始的array1相同:
order = _.object(_.map(array1, function(obj, i) { return [obj.field, i]; }))
_.sortBy(_.values(_.extend(_.indexBy(array1, 'field'), _.indexBy(array2, 'field'))), function(obj) { order[obj.field]; })

在这里,我们制作了一个位置的查找表,然后根据查找表对原始解进行排序。


谢谢,那正是我想要的。我该如何保留顺序。我的意思是,我希望顺序与第一个数组中的顺序保持一致。第二个数组不会有任何新元素。它只用于更新。 - user3214546
我有两个列表,第一个是:[{"image_id": 631293, "score": 73}, {"image_id": 11848407, "score": 56}],第二个是[{"image_id": 631293, "article_id": 173}, {"image_id": 11848407, "article_id": 121}]。如果我尝试应用你的方法,它不会改变任何东西。 - Toucouleur
@Toucouleur 你可能想要将 'field' 替换为 'image_id',因为看起来那是你的关键字段。 - Aaron Dufour
我晚了将近3年,但这个答案正是我在寻找的。非常感谢! :) - Terry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接