在javascript中按id和按属性分组连接两个对象数组

x7rlezfr  于 2021-09-23  发布在  Java
关注(0)|答案(1)|浏览(273)

我想使用“id”属性连接2个对象数组(文件x计数),然后,我想按“folder”属性分组,将每个“folder”的所有计数相加。最后的结果是我不想有“id”属性
文件数组:

const file = [{
  id: "xxx",
  folder: "A"
},{
  id: "bbb",
  folder: "B"
},{
  id: "ccc",
  folder: "B"
},{
  id: "ddd",
  folder: "C"
},{
  id: "aaa",
  folder: "C"
},{
  id: "ggg",
  folder: "A"
}]

计数数组:

const counts = [{
  id: "bbb",
  actions: {
    download: 5,
    seen: 10,
    shared: 3
  }
},{
  id: "xxx",
  actions: {
    download: 2,
    seen: 5,
    shared: 8
  }
},{
  id: "ccc",
  actions: {
    download: 7,
    seen: 9,
    shared: 5
  }
},{
  id: "ggg",
  actions: {
    download: 0,
    seen: 2,
    shared: 3
  }
},{
  id: "eee",
  actions: {
    download: 50,
    seen: 55,
    shared: 3
  }
},{
  id: "fff",
  actions: {
    download: 5,
    seen: 4,
    shared: 3
  }
}]

结果:

const result = [{
  folder: "A",
  actions: {
    download: 2,
    seen: 7,
    shared: 11
  }
},{
  folder: "B",
  actions: {
    download: 12,
    seen: 19,
    shared: 8
  }
},{
  folder: "C"
}]

我的代码:

const join = files.reduce((arr, e) => {
  arr.push(Object.assign({}, e, counts.find(a => a.id == e.id)))
  return arr;
}, [])

join.forEach(function(v){ delete v.id });

const result = Object.values(
                 join.reduce((a, c) => (
                   a[c.folder] = a[c.folder] && a[c.folder].actions?
                   (a[c.folder].actions.download += c.actions.download,
                   a[c.folder].actions.seen += c.actions.seen,
                   a[c.folder].actions.shared += c.actions.shared , 
                   a[c.folder]) :
                   c, a), {}
                 )
               )

有没有一种合适的方法可以在更少的线路上进行优化?
事先非常感谢。

y0u0uwnf

y0u0uwnf1#

另一种方法是
使用Map将文件Map到其关联的文件夹,以便以后快速查找(相反, .findO(n) )
不要 delete 这个 id 属性-而是在循环计数时使用它们查找与id关联的文件夹。
在每次迭代中,如果给定id的文件夹不存在,则立即继续停止该迭代。否则,迭代相关对象的所有属性,并将它们与该文件夹的累积结果对象合并。

const file=[{id:"xxx",folder:"A"},{id:"bbb",folder:"B"},{id:"ccc",folder:"B"},{id:"ddd",folder:"C"},{id:"aaa",folder:"C"},{id:"ggg",folder:"A"}],counts=[{id:"bbb",actions:{download:5,seen:10,shared:3}},{id:"xxx",actions:{download:2,seen:5,shared:8}},{id:"ccc",actions:{download:7,seen:9,shared:5}},{id:"ggg",actions:{download:0,seen:2,shared:3}},{id:"eee",actions:{download:50,seen:55,shared:3}},{id:"fff",actions:{download:5,seen:4,shared:3}}];

const foldersById = new Map();
for (const { id, folder } of file) {
  foldersById.set(id, folder);
}
const resultMap = new Map(
  [...foldersById.values()]
    .map(folder => [folder, ({ folder, actions: {}})])
);
for (const { id, actions } of counts) {
  const folder = foldersById.get(id);
  if (!folder) continue;
  const resultActions = resultMap.get(folder).actions;
  for (const [key, value] of Object.entries(actions)) {
    resultActions[key] = (resultActions[key] || 0) + value;
  }
}
const result = [...resultMap.values()];
console.log(result);

相关问题