javascript 合并两个对象数组

whhtz7ly  于 2022-12-25  发布在  Java
关注(0)|答案(4)|浏览(167)

我尝试将这两个对象数组组合在一起,并获得以下输出。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));
uqcuzwp8

uqcuzwp81#

你可以用一个对象来减少,并使用一个默认的对象来使值无效。

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; }
ekqde3dh

ekqde3dh2#

在这种情况下,通常使用Maps/Dictionary/(key/value)数据结构是很好的,这里key是用户标识,value是你想要存储的属性。

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))

zwghvu4y

zwghvu4y3#

这是我能想到的使用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));
vql8enpb

vql8enpb4#

您可以使用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 ) ?? {})}]
}, [])

相关问题