每个项目的唯一 ID 的映射计数

Mapping count of unique IDs per project

我收到了一个像这样的对象数组

[
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project One"
             }
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project Two"
             }
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project Two"
             }
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"54323",
                "project":"Project One"
             }
          }
       }
    }
]

我想做的是计算每个项目的所有唯一 customerId。所以对于上面的数据,我希望

Project One: 2
Project Two: 1 //because 12345 is shown twice for Project Two, we only want unique so count it as 1

所以我可以使用地图进行计数,就像这样

const lutProjects = new Map();
Object.entries(data).forEach(([key, value]) => {
  const project = value?.payload?.correlation?.metadata?.project;
  const custId = value?.payload?.correlation?.metadata?.customerId;
  
  lutProjects.set(project, (lutProjects.get(project) || 0) + 1);
});

但是,这不会处理每个项目的唯一 ID,因此输出 2 和 2。

如何处理每个项目的唯一 ID?

我创建了一个JSFiddle

谢谢

您可以尝试使用以下代码段进行快速修复

let data = [{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project One"}}}},{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project Two"}}}},{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project Two"}}}},{"payload":{"correlation":{"metadata":{"customerId":"54323","project":"Project One"}}}}]

data = Array.from(new Set(data.map(f => f.payload.correlation.metadata.project))).map(d => {
   return {
      [d]: [...new Set(data.filter(f => f.payload.correlation.metadata.project === d).map(c => c.payload.correlation.metadata.customerId))].length
   }
});

console.log(data);

reduce method 与每个项目的唯一 ID 数组结合使用,然后使用这些数组的长度来了解最终计数。 这是我的提议:

const arr = [
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project One"
             } 
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project Two"
             }
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"12345",
                "project":"Project Two"
             }
          }
       }
    },
    {
       "payload":{
          "correlation":{
             "metadata":{
                "customerId":"54323",
                "project":"Project One"
             }
          }
       }
    }
]

const cb = (accumulator, { payload }) => {
    const { project, customerId } = payload.correlation.metadata
    if (!accumulator[project]) {
      return { ...accumulator, [project]: [customerId] }
    }
    else if (accumulator[project] && accumulator[project].indexOf(customerId) === -1) {
    return { ...accumulator, [project]: [...accumulator[project], customerId] }
    } else return accumulator
}

const initialAccumulator = {}

const result1 = arr.reduce(cb, initialAccumulator)
const result2 = Object.keys(result1).map(key => ({ [key]: result1[key].length }))
console.log(result2)

如果使用reduce()创建一个对象,以project为键,值为包含customerId的数组,我们可以使用includes()来检查此 customerId 是否已知,如果已知则仅将其添加到数组中。

然后,我们可以使用第二个 reduce() 将数组 ow customerId 更改为数组的 length

const data = [{"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project One"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project Two"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project Two"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"54323", "project":"Project One"} } } } ];

let res = data.reduce((prev, cur) => {
    const { customerId, project } = cur.payload.correlation.metadata;
    if (!prev[project]) prev[project] = [];
    if (!prev[project].includes(customerId)) {
      prev[project].push(customerId);
    }
    return prev;
}, {});
res = Object.keys(res).reduce((prev, cur) => ({ ...prev, [cur]: res[cur].length }), {});

console.log(res);

{
  "Project One": 2,
  "Project Two": 1
}