如何有效地对对象进行分组并为每组对象进行计算

时间:2019-05-15 10:54:30

标签: javascript arrays json object

我正在使用从Java API获取一些数据的JavaScript应用程序,这就是数据集的一些记录的样子:

    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "45.665", nodeId: "1", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-                                        
    05-2019 10:56:28", duration: "47.602", nodeId: "9", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "5.287", nodeId: "12", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "5.932", nodeId: "27", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "56.918", nodeId: "9", …}

如您所见,它是一组对象,现在我要做的是,将这组对象按nodeId分组。因此,我可以对每个nodeId进行计算。我想要每个nodeId的平均持续时间。但是我真的不知道从哪里开始/如何有效地做到这一点。

我认为必须使用一些filter / map / reduce,对吗?

感谢

3 个答案:

答案 0 :(得分:0)

您可以拿一个对象并存储每个nodeId的总和,计数和平均值。

var data = [{ eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "47.602", nodeId: "9" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.287", nodeId: "12" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.932", nodeId: "27" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10: 56: 28", duration: "56.918", nodeId: "9" }],
    result = data.reduce((r, { duration, nodeId }) => {
        r[nodeId] = r[nodeId] || { sum: 0, count: 0, average: 0 };
        r[nodeId].sum += +duration;
        r[nodeId].average = r[nodeId].sum / ++r[nodeId].count;
        return r;
    }, {});

console.log(result)

答案 1 :(得分:0)

使用reducenodeId分组并创建持续时间数组。然后,您可以使用map来获取持续时间的平均值

const input = [
{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1"},
{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "47.602", nodeId: "9"},
{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.287", nodeId: "12"},
{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.932", nodeId: "27"},
{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "56.918", nodeId: "9"}];

const groupByNodeId = Object.values(input.reduce((accu, {nodeId, duration, ...rest}) => {
    if(!accu[nodeId]) {
        accu[nodeId] = {...rest, nodeId, durations : []};
    } 
    // console.log(accu[nodeId]);
    accu[nodeId].durations.push(Number(duration));
    return accu;
}, {}));

const getSum = (arr) => arr.reduce((accu, num) => accu+num);
const output = groupByNodeId.map(({durations, ...rest}) => ({...rest, durationAvg: getSum(durations)/durations.length}));
console.log(output);

答案 2 :(得分:0)

我相信这就是您想要的-使用reduce

const data = [{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019-10:56:28", duration: "47.602", nodeId: "9"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.287", nodeId: "12"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.932", nodeId: "27"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "56.918", nodeId: "9"}];

const res = data.reduce((acc, curr) => {
  acc[curr.nodeId] = acc[curr.nodeId] ? acc[curr.nodeId].concat(curr) : [curr];
  return acc;
}, {});

console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }