通过数组中的多个属性获得多个总和

get multiple sums by multiple properties in array

我这里有一个非常困难的方法。使用此示例数据:

[
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 20,"numItems": 1},
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 65,"numItems": 20},
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 20,"numItems": 3},
    {"idClient": 1,"idProject": 1,"sourceLanguage": 26,"targetLanguage": 71,"numItems": 12},
    {"idClient": 2,"idProject": 3,"sourceLanguage": 20,"targetLanguage": 65,"numItems": 1}
]

我需要求和的倍数:

示例结果应该是这样的:

[{
    "idClient": 1,
    "numItems": 36,
    "proyects": [
        {
            "idProyect": 8,
            "numItems": 24,
            "sourceLanguages":[
                {
                "id":26,
                "numItems": 21
                },
                {
                 "id": 30,
                "numItems": 3 
                }
            ]
        },
        {
            "idProject": 1,
            "numItems": 12,
            "sourceLanguages":[{
                "id":26,
                "numItems": 12,
                },
                {
                    "id": 30,
                    "numItems": 3, 
                }
                
            ]
        }]
}]

我有一个简单的函数,可以单独获得前两个总和,并在一个对象中 return(从键中删除 idProject 以获得每个客户的总和):

const totalPerClient_Project= [...data.reduce((r, o) => {
        const key = o.idClient + '-' + o.idProject;

        const item = r.get(key) || Object.assign({}, o, {
          numItems: 0
        });

        item.numItems += o.numItems;

        return r.set(key, item);
      }, new Map).values()];

但我发现很难通过 3 个链接属性获得 sum。这种方法是否可以使用独特的功能?

我认为您可以使用一个 reduce 函数完成所有这些工作。

const data = [
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 20,"numItems": 1},
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 65,"numItems": 20},
    {"idClient": 1,"idProject": 8,"sourceLanguage": 26,"targetLanguage": 20,"numItems": 3},
    {"idClient": 1,"idProject": 1,"sourceLanguage": 26,"targetLanguage": 71,"numItems": 12},
    {"idClient": 2,"idProject": 3,"sourceLanguage": 20,"targetLanguage": 65,"numItems": 1}
]

const group1 = data.reduce((acc, value) => {
  let client = acc.find(pr => pr.idClient === value.idClient)
  
  if(!client) {
   client = {
    idClient: value.idClient,
    numItems: 0,
    projects: [],
   }
  
   acc.push(client);
  }
  
  client.numItems++;
  
  let project = client.projects.find(pr => pr.idProject === value.idProject)
  
  if(!project) {
   project = {
    idProject: value.idProject,
    numItems: 0,
    sourceLanguages: [],
   }
   
   client.projects.push(project);
  }
  
  project.numItems++;
  
  let sourceLanguage = project.sourceLanguages.find(pr => pr.id === value.sourceLanguage)
  
  if(!sourceLanguage) {
   sourceLanguage = {
    id: value.sourceLanguage,
    numItems: 0,
    sourceLanguages: [],
   }
   
   project.sourceLanguages.push(sourceLanguage);
  }
  
  sourceLanguage.numItems++;
  
  return acc;
}, [])

console.log(group1);