如何在一个循环中组合/合并/交叉两个对象数组?

时间:2018-04-19 05:05:13

标签: javascript arrays filter ecmascript-6 javascript-objects

此代码有效,但我觉得必须有更好的方法,而不必使用Array.find()两次。



const people = [
  { id: 0, age: 99 },
  { id: 1, age: 54 },
  { id: 2, age: 54 }
];
const roles = [
  { pId: 0, responsabilites: ['make money'] },
  { pId: 1, responsabilites: ['make money', 'complain'] },
  { pId: 4, responsabilites: ['make the world a better place', 'sarcasmm'] },
];

let roomsAndOrders = people.filter(p => {
  return roles.find(r => r.pId === p.id);
});
roomsAndOrders = roomsAndOrders.map(p => {
  let r = roles.find(r => r.pId === p.id);
  return { ...r, ...p };
});
   
console.log(roomsAndOrders);




2 个答案:

答案 0 :(得分:2)

只需使用一个.map。您的原始filter没有多大意义 - filter过滤掉您不想要的数组中的元素,但它不会更改元素。您正在从filter函数返回对象,并且对象是真实的,因此filter实际上并没有做任何事情。

修改:或者只是反过来映射 - 一次从roles映射到people,而不是从people映射到roles



const people = [
  { id: 0, age: 99 },
  { id: 1, age: 54 },
  { id: 2, age: 54 }
];
const roles = [
  { pId: 0, responsabilites: ['make money'] },
  { pId: 1, responsabilites: ['make money', 'complain'] },
];

const roomsAndOrders = roles.map(role => {
  const person = people.find(({ id }) => role.pId === id);
  return { ...role, ...person };
});
console.log(roomsAndOrders);




要仅包含ID在两个数组中的对象,您必须使用.reduce,因为map始终返回与原始数组中相同数量的元素:



const people = [
  { id: 0, age: 99 },
  { id: 1, age: 54 },
  { id: 2, age: 54 }
];
const roles = [
  { pId: 0, responsabilites: ['make money'] },
  { pId: 1, responsabilites: ['make money', 'complain'] },
  { pId: 4, responsabilites: ['make the world a better place', 'sarcasmm'] },
];

const roomsAndOrders = roles.reduce((accum, role) => {
  const person = people.find(({ id }) => role.pId === id);
  if (person) accum.push({ ...role, ...person });
  return accum;
}, []);
console.log(roomsAndOrders);




答案 1 :(得分:1)

您可以使用哈希表在O(n)中执行此操作:

 const result = [], hash = {};

 for(const person of people)
   result.push(hash[person.id] = {...person});

for(const role of roles)
  if(hash[role.pId])
    Object.assign(hash[role.pId], role);