how to group nested obects using underscorejs and get the matching data length

35 views Asked by At

How to group the matching data in array of object and get the matching data length to get the average value.

var getdataObj = [{
  "finalUrl": "https://www.amazon.in/",
  "fetchTime": "2022-10-15T08:58:18.485Z",
  "audits": {   
    "first-contentful-paint": {
      "displayValue": "1.2"
    },
    }
},
{
  "finalUrl": "https://www.google.in/",
  "fetchTime": "2022-11-15T08:58:18.485Z",
  "audits": {   
    "first-contentful-paint": {
      "displayValue": "6.2"
    },
    }
},
{
  "finalUrl": "https://www.flipkart.in/",
  "fetchTime": "2022-10-15T08:58:18.485Z",
  "audits": {   
    "first-contentful-paint": {
      "displayValue": "4.2"
    },
    }
},
{
  "finalUrl": "https://www.amazon.in/",
  "fetchTime": "2022-10-15T08:58:18.485Z",
  "audits": {   
    "first-contentful-paint": {
      "displayValue": "3.7"
    },
    }
},
{
  "finalUrl": "https://www.google.in/",
  "fetchTime": "2022-12-15T08:58:18.485Z",
  "audits": {   
    "first-contentful-paint": {
      "displayValue": "3.2"
    },
    }
}]

This is the array of object I am getting. How to group the matching elements here.

  • Need to group the matching URL.
  • Seperate the value based on month and Year.

Expected Result :

https://www.amazon.in/ month : 2022-10 TotalValue : 4.9 //(1.2+3.7)

My Code Logic :

var groupedData = _.chain(getdataObj)
          .groupBy('fetchTime')
          .map(function (group, datekey) {
          return {
              Month: datekey.substr(0,7),
                WTs: _.chain(group)
                  .groupBy("finalUrl")
                  .map(function (group, key) {
                  return {
                      WT: key,
                     TotalWeight: _.reduce(group, function(acc, i){ 
                          acc.speed += parseFloat(i['audits']['first-contentful-paint']['displayValue']);                         
                          return acc; 
                      }, {speed : 0})
                  };
              })
              .value()
          }})
          .value();

And i need to get the length. Ex : I have three datas in October month. So my Avarage calculation should be,

https://www.amazon.in/ month : 2022-10

https://www.flipkart.in/ month : 2022-10

TotalValue : 9.1 / 3 => 3.03

Can anyone please help me to fix this issue.

Sample fiddle i added here : JSFiddle

var data = [{
    fetchTime: '2022-12-15T08:58:18.485Z',
    finalUrl: 'https://www.amazon.in/',
    audits: {
        "first-contentful-paint": {
        "displayValue": "3.4"
    },
    "largest-contentful-paint": {
      "displayValue": "2.3"
    },
    }
}, {
    fetchTime: '2022-12-15T08:58:18.485Z',
    finalUrl: 'https://www.google.in/',
    audits: {
    "first-contentful-paint": {
        "displayValue": "1.2"
    },
    "largest-contentful-paint": {
      "displayValue": "3.4"
    },
    }
}, {
    fetchTime: '2023-02-15T08:58:18.485Z',
    finalUrl: 'https://www.amazon.in/',
    audits: {
    "first-contentful-paint": {
        "displayValue": "6.2"
    },
    "largest-contentful-paint": {
      "displayValue": "3.5"
    },
    }
}, {
    fetchTime: '2022-11-15T08:58:18.485Z',
    finalUrl: 'https://www.flipkart.in/',
    audits: {
    "first-contentful-paint": {
        "displayValue": "4.2"
    },
    "largest-contentful-paint": {
      "displayValue": "5.3"
    },
    }
}, {
    fetchTime: '2023-01-15T08:58:18.485Z',
    finalUrl: 'https://www.google.in/',
    audits: {
    "first-contentful-paint": {
        "displayValue": "7.2"
    },
    "largest-contentful-paint": {
      "displayValue": "8.3"
    },
    }
}];

var groupedData = _.chain(data)
    .groupBy('fetchTime')
    .map(function (group, key) {
    return {
        Month: key,
        WTs: _.chain(group)
            .groupBy("finalUrl")
            .map(function (group, key) {
            return {
                WT: key,
                TotalWeight: _.reduce(group, function(acc, i){ 
                    acc.speed += parseFloat(i['audits']['first-contentful-paint']['displayValue']);
                    acc.large += parseFloat(i['audits']['largest-contentful-paint']['displayValue']);
                }, {speed:0, large:0})
            };
        })
        .value()
    }})
    .value();


console.log(groupedData);

_.each(groupedData, function(m) {
    console.log("Month: ", m.Month);
    _.each(m.WTs, function(wt) {
        console.log("  ", wt.WT,  ": ", wt.TotalWeight);
    });
});

2

There are 2 answers

0
Julian On BEST ANSWER

You were almost there. The function that you pass to reduce, also known as the iteratee, must return the new value of the accumulator. In order to also collect the length, simply add it to the object returned from the map iteratee.

var data = [{
    fetchTime: '2022-12-15T08:58:18.485Z',
    finalUrl: 'https://www.amazon.in/',
    audits: {
        "first-contentful-paint": {
            "displayValue": "3.4"
        },
        "largest-contentful-paint": {
            "displayValue": "2.3"
        },
    }
}, {
    fetchTime: '2022-12-15T08:58:18.485Z',
    finalUrl: 'https://www.google.in/',
    audits: {
        "first-contentful-paint": {
            "displayValue": "1.2"
        },
        "largest-contentful-paint": {
          "displayValue": "3.4"
        },
    }
}, {
    fetchTime: '2023-02-15T08:58:18.485Z',
    finalUrl: 'https://www.amazon.in/',
    audits: {
        "first-contentful-paint": {
            "displayValue": "6.2"
        },
        "largest-contentful-paint": {
          "displayValue": "3.5"
        },
    }
}, {
    fetchTime: '2022-11-15T08:58:18.485Z',
    finalUrl: 'https://www.flipkart.in/',
    audits: {
        "first-contentful-paint": {
            "displayValue": "4.2"
        },
        "largest-contentful-paint": {
          "displayValue": "5.3"
        },
    }
}, {
    fetchTime: '2023-01-15T08:58:18.485Z',
    finalUrl: 'https://www.google.in/',
    audits: {
        "first-contentful-paint": {
            "displayValue": "7.2"
        },
        "largest-contentful-paint": {
          "displayValue": "8.3"
        },
    }
}];

function yearMonth(dateString) {
    return dateString.slice(0, 7);
}

var groupedData = _.chain(data)
    .groupBy(_.compose(yearMonth, _.property('fetchTime')))
    .map(function (group, key) {
        return {
            Month: key,
            WTs: _.chain(group)
                .groupBy("finalUrl")
                .map(function (group, key) {
                    return {
                        WT: key,
                        TotalWeight: _.reduce(group, function(acc, i){ 
                            acc.speed += parseFloat(i['audits']['first-contentful-paint']['displayValue']);
                            acc.large += parseFloat(i['audits']['largest-contentful-paint']['displayValue']);
                            return acc;
                        }, {speed:0, large:0}),
                        length: group.length
                    };
                })
                .value()
        };
    })
    .value();

_.each(groupedData, function(m) {
    console.log("Month: ", m.Month);
    _.each(m.WTs, function(wt) {
        console.log("  ", wt.WT,  ": ", wt.TotalWeight);
        console.log('Average speed: ', wt.TotalWeight.speed / wt.length);
        console.log('Average large: ', wt.TotalWeight.large / wt.length);
    });
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/underscore-umd-min.js"></script>

0
Nina Scholz On

You could take a combined key for grouping and add displayValue to total.

const
    data = [{ finalUrl: "https://www.amazon.in/", fetchTime: "2022-10-15T08:58:18.485Z", audits: { "first-contentful-paint": { displayValue: "1.2" } } }, { finalUrl: "https://www.google.in/", fetchTime: "2022-11-15T08:58:18.485Z", audits: { "first-contentful-paint": { displayValue: "6.2" } } }, { finalUrl: "https://www.flipkart.in/", fetchTime: "2022-10-15T08:58:18.485Z", audits: { "first-contentful-paint": { displayValue: "4.2" } } }, { finalUrl: "https://www.amazon.in/", fetchTime: "2022-10-15T08:58:18.485Z", audits: { "first-contentful-paint": { displayValue: "3.7" } } }, { finalUrl: "https://www.google.in/", fetchTime: "2022-12-15T08:58:18.485Z", audits: { "first-contentful-paint": { displayValue: "3.2" } } }],
    result = Object.values(data.reduce((r, { finalUrl, fetchTime, audits: { ["first-contentful-paint"]: { displayValue } } }) => {
        const
            month = fetchTime.slice(0, 7),
            key = [finalUrl, month].join('|');
            
        r[key] ??= { finalUrl, month, total: 0 };
        r[key].total += +displayValue;
        
        return r;
    }, {}));

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