Search code examples
javascriptarraysobjectgrouping

Group array of objects with a specific key value pushed first


Given the following Array of Objects:

[
    {
        "teamFK": 8650,
        "code": "yellow_cards",
        "typeId": 554,
        "value": "5",
        "side": "home"
    },
    {
        "teamFK": 8650,
        "code": "goals",
        "typeId": 554,
        "value": "1",
        "side": "home"
    },
    {
        "teamFK": 8990,
        "code": "yellow_cards",
        "typeId": 555,
        "value": "2",
        "side": "away"
    },
    {
        "teamFK": 8990,
        "code": "goals",
        "typeId": 555,
        "value": "0",
        "side": "away"
    }
]

I would like to group this data by code and get this result:

{
      "stats": [
        {
          "name": "yellow_cards",
          "stats": ["5","2"]
        },
        {
          "name": "goals",
          "stats": ["2","0"]
        }
      ]
}

What I've done is the following which works but I want to make sure that the alway the stat with "side":"home" always pushed first into the array "stats": []:

 const groupedStats = Object.entries(
    query.reduce((acc, { typeId, value, code, side }) => {
      if (!acc[code]) {
        acc[code] = [];
      }

      acc[code].push(value);

      return acc;
    }, {}),
  ).map(([name, stats]) => ({ name, stats }));

Solution

  • My approach is sort it first by side using Array.sort() and then looping through the objects and adding it to stats

    i created a const match to find if there is a match already so i dont have to add the name and value again basically if its not a match i'll add it to the stats array and if its a match then i'll just update the current index

    const objs = [
      {
        teamFK: 8650,
        code: "yellow_cards",
        typeId: 554,
        value: "5",
        side: "home",
      },
      {
        teamFK: 8650,
        code: "goals",
        typeId: 554,
        value: "1",
        side: "away",
      },
      {
        teamFK: 8990,
        code: "yellow_cards",
        typeId: 555,
        value: "2",
        side: "away",
      },
      {
        teamFK: 8990,
        code: "goals",
        typeId: 555,
        value: "0",
        side: "home",
      },
    ];
    let stats = [];
    
    const transformedObj = objs
      .sort((a, b) => {
        if (a.side > b.side) {
          return -1;
        }
        if (a.side < b.side) {
          return 1;
        }
        return 0;
      })
      .forEach((obj) => {
        const match = stats.find((stat) => stat.name === obj.code);
        const statsIndex = stats.findIndex((stat) => stat.name === obj.code);
        if (!match) {
          stats = [...stats, { name: obj.code, value: [obj.value] }];
        } else {
          stats[statsIndex] = {
            name: stats[statsIndex].name,
            value: [...stats[statsIndex].value, obj.value],
          };
        }
      });
    
    console.log(stats);