首页 > 解决方案 > JavaScript - 有没有办法通过指定的键属性合并 2 个对象?

问题描述

JavaScript - 有没有办法通过指定的键属性合并 2 个对象?在这种情况下,关键属性是authorId.

注意:作者 3 和作者 1 没有匹配项,因此不应合并。

var b = [{"book": "book1", "authorId": 3},{"book": "book2", "authorId":2}];

var a = [{"authorId": 1, "author": "author1"},{"authorId": 2, "author": "author2"}];

var c = a.merge(b);

console.log(c);

期待:

[{"book": "book2", "authorId": 2, "author": "author2"}]

我试图在这里完成 SQL JOIN 的作用。

https://jsfiddle.net/x67fpwoj/4/

标签: javascriptnode.js

解决方案


map通过Object.assign从另一个数组中具有相同索引的项目:

var b = [{"book": "book1", "authorId": 1},{"book": "book2", "authorId":2}];
var a = [{"authorId": 1, "author": "author1"},{"authorId": 2, "author": "author2"}];
var c = a.map((aItem, i) => Object.assign({}, aItem, b[i]));
console.log(c);

如果您不能指望每个数组都被排序,那么您可能会reduce进入一个由 索引的对象authorId,然后获取该对象的值(这具有O(N)复杂性,而不是.find每次迭代都具有O(N^2)复杂性):

var a = [{"authorId": 1, "author": "author1"},{"authorId": 2, "author": "author2"}];
var b = [{"book": "book1", "authorId": 1},{"book": "book2", "authorId":2}];

const reduceByAuthor = (arr, initial = {}) => arr.reduce((a, item) => {
  a[item.authorId] = Object.assign((a[item.authorId] || {}), item);
  return a;
}, initial);

const indexedByAuthor = reduceByAuthor(a);
reduceByAuthor(b, indexedByAuthor);
console.log(Object.values(indexedByAuthor));

如果您不能指望每个项目在另一个数组中具有匹配项,那么reduce两次,reduce只有在第一个索引对象中找到匹配项时才将第二个分配给累加器(比filtering之后更快):

var b = [{"book": "book1", "authorId": 3},{"book": "book2", "authorId":2}];
var a = [{"authorId": 1, "author": "author1"},{"authorId": 2, "author": "author2"}];

const aIndexed = a.reduce((a, item) => {
  a[item.authorId] = item;
  return a;
}, {});
const c = Object.values(b.reduce((a, bItem) => {
  const { authorId } = bItem;
  const aItem = aIndexed[authorId];
  if (aItem) a[authorId] = Object.assign({}, aItem, bItem);
  return a;
}, {}))

console.log(c);


推荐阅读