繁体   English   中英

合并两个对象数组

[英]Combine two arrays of objects

我试图将这两个对象数组组合在一起并获得下面的输出。 userid属性应该是唯一的,但不是namerole

输入

const first = [
  { userid: 2, name: "Velen" },
  { userid: 56, name: "Illidan" },
  { userid: 23, name: "Muradin" },
  { userid: 12, name: "Sylvanas" },
  { userid: 44, name: "Cenarius" },
  { userid: 4, name: "Gul'Dan" },
];

const second = [
  { userid: 2, role: "Mage" },
  { userid: 4, role: "Worlock" },
  { userid: 56, role: "Demon Hunter" },
  { userid: 66, role: "Druid" },
  { userid: 87, role: "Shaman" },
  { userid: 12, role: "Hunter" },
];

输出

[
    { name: 'Velen',    role: 'Mage',       userid: 2 },
    { name: "Gul'Dan",  role: 'Worlock',    userid: 4 },
    { name: 'Sylvanas', role: 'Hunter',     userid: 12 },
    { name: 'Muradin',  role: null,         userid: 23 },
    { name: 'Cenarius', role: null,         userid: 44 },
    { name: 'Illidan',  role: 'Demon Hunter', userid: 56 },
    { name: null,       role: 'Druid',      userid: 66 },
    { name: null,       role: 'Shaman',     userid: 87 }
]

我试过这个解决方案,但没有用:

const solution = (first, second) => {
  first.sort((a, b) => a.userid - b.userid);
  second.sort((a, b) => a.userid - b.userid);
  first.map((item, idx) => {
    return {
      a: (item.role = second[idx].role),
      b: (item.userid = second[idx].userid),
    };
  });
  return first;
};
console.log(solution(first, second));

您可以使用对象进行缩减,并采用具有无效值的默认对象。

 const first = [{ userid: 2, name: "Velen" }, { userid: 56, name: "Illidan" }, { userid: 23, name: "Muradin" }, { userid: 12, name: "Sylvanas" }, { userid: 44, name: "Cenarius" }, { userid: 4, name: "Gul'Dan" }], second = [{ userid: 2, role: "Mage" }, { userid: 4, role: "Worlock" }, { userid: 56, role: "Demon Hunter" }, { userid: 66, role: "Druid" }, { userid: 87, role: "Shaman" }, { userid: 12, role: "Hunter" }], result = Object.values([...first, ...second].reduce((r, o) => { Object.assign(r[o.userid]??= { name: null, role: null }, o); return r; }, {})); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

您可以使用reduce函数来执行此操作,如下所示:

// adding empty model to make sure we'll get all keys
const emptyObj = {role: null, name: null}
const emptyObj = {role: null, name: null}
const userids = [...new Set([...first, ...second].map(item => item.userid))]

const output = userids.reduce((acc, cur) => {

  return [...acc, {...emptyObj, ...cur, ...(second.find(({userid}) => userid === cur ) ?? {}), ...(first.find(({userid}) => userid === cur ) ?? {})}]
}, [])

在这种情况下,通常使用 Maps/Dictionary/(键/值)数据结构非常好。 在这种情况下,键是用户标识,值是您要存储的属性。

 const first = [ { userid: 2, name: "Velen" }, { userid: 56, name: "Illidan" }, { userid: 23, name: "Muradin" }, { userid: 12, name: "Sylvanas" }, { userid: 44, name: "Cenarius" }, { userid: 4, name: "Gul'Dan" }, ]; const second = [ { userid: 2, role: "Mage" }, { userid: 4, role: "Worlock" }, { userid: 56, role: "Demon Hunter" }, { userid: 66, role: "Druid" }, { userid: 87, role: "Shaman" }, { userid: 12, role: "Hunter" }, ]; const solution = (first, second) => { const combined = new Map(); for (const item of first) { combined.set(item.userid, {...item, role: null }); } for (const item of second) { if (combined.has(item.userid)) { combined.get(item.userid).role = item.role; } else { combined.set(item.userid, {...item, name: null }); } } return Array.from(combined.values()).sort((a, b) => a.userid - b.userid); }; console.log(solution(first, second));

最后,我们像您尝试做的那样使用 userid 进行排序。 如果没有排序,解决方案的时间复杂度为O(n) 排序是O(n*log(n))

这是我能想到的最好的使用 reduce 的方法,不得不使用其中两个来达到想要的结果。 假设第一个数组始终包含useridname而第二个数组始终包含useridrole

 const first = [ { userid: 2, name: "Velen" }, { userid: 56, name: "Illidan" }, { userid: 23, name: "Muradin" }, { userid: 12, name: "Sylvanas" }, { userid: 44, name: "Cenarius" }, { userid: 4, name: "Gul'Dan" }, ]; const second = [ { userid: 2, role: "Mage" }, { userid: 4, role: "Worlock" }, { userid: 56, role: "Demon Hunter" }, { userid: 66, role: "Druid" }, { userid: 87, role: "Shaman" }, { userid: 12, role: "Hunter" }, ]; const solution = (first, second) => { const firstReduce = first.reduce((acc, curr) => { const roleElem = second.find(elem => elem.userid === curr.userid); if (roleElem) { return [...acc, {...curr, role: roleElem.role}]; } return [...acc, {...curr, role: null}]; }, []); const secondReduce = second.reduce((acc, curr) => { const elem = firstReduce.find(elem => elem.userid === curr.userid); if (.elem) { return [..,acc. {..,curr: name; null}]; } return acc, }; firstReduce); return secondReduce. } console,log(solution(first; second));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM