Search code examples
javascriptarraysecmascript-6lodash

Group Nested array by value and find average


Most other answer shows hot to group array of object but not array of arrays. Looking to group nested arrays and find average of the rest of the items

I am looking to group an array by the url (2nd item in array) and find average of rest of the item. So we should be able to group all url with same path for eg "/url/ranking" which have can be found in 2 sub arrays whereas /different/url in three. I am also looking to find average of rest of the numbers when we group the array based on the url.

[
 [
    'randomstring4',
    "/url/ranking/",
    12.1176,
    76.8978,
    8.8990
 ],
 [
    'randomstring3',
    "/url/ranking/",
    33.76,
    24.8978,
    7.8990
 ],
 [
    'randomstring2',
    "/different/url/",
    42.1176,
    26.8978,
    83.8990
 ],
 [
    'randomstring1',
    "/different/url/",
    33.76,
    24.8978,
    73.8990
 ],
 [
    'randomstring1',
    "/different/url/",
    13.689,
    4.118,
    53.03
 ],

]

In above example we will group by the url and get average for rest of items for eg

[ 'randomstring4', "/url/ranking/", 22.93, // (12.1176+33.76)/2 50.89, 8.39 ]

This would provide a means to get scoring of url from different website and find and average score upon data produced.

Here is the result with one of the array item (rest may need to be calculated accordingly)

[ 
'randomstring4', 
"/url/ranking/", 
22.93, // (12.1176+33.76)/2 50.89, 8.39 ]
 (76.8978+24.8978)/2),
( 8.8990+7.8990)/2
]

My trial here https://codepen.io/anon/pen/ymJbPe


Solution

  • You could group the items first by taking the value with their sum and count and render the result array with the grouped data.

    var data = [['randomstring4', "/url/ranking/", 12.1176, 76.8978, 8.8990], ['randomstring3', "/url/ranking/", 33.76, 24.8978, 7.8990], ['randomstring2', "/different/url/", 42.1176, 26.8978, 83.8990], ['randomstring1', "/different/url/", 33.76, 24.8978, 73.8990], ['randomstring1', "/different/url/", 13.689, 4.118, 53.03]],
        groups = data.reduce((g, array) => {
            var key = array[1];
            g[key] = g[key] || [];
            array.slice(2).forEach((v, i) => {
                g[key][i] = g[key][i] || { sum: 0, count: 0 };
                g[key][i].sum += v;
                g[key][i].count++;
            });
            return g;
        }, {}),
        result = Object
            .entries(groups)
            .map(([group, values]) => (['', group, ...values.map(({ sum, count }) => sum / count)]));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }