Home > OS >  Create objects from array of objects based on equal keys value Javascript
Create objects from array of objects based on equal keys value Javascript

Time:04-27

I have an array of objects that can have three forms:

First form is as follows (where is just one record per roundId):

[{
    "roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
    "teamId": null,
    "score": null
  },
  {
    "roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
    "teamId": null,
    "score": null
  },
  {
    "roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
    "teamId": null,
    "score": null
  }
]

And the second form can be like this (where there can be two records and one record per roundId):

[{
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 21
  },
  {
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 20
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 18
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 7
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": null,
    "score": null
  }
]

And the last form (where there can be two records for a roundId):

[{
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 21
  },
  {
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 20
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 18
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 7
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 19
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 12
  }
]

I need that based on the roundId key to return a new array of objects, where an object is formed of two keys: roundId and teams where teams is an array of objects formed of teamdId and score.

If the teamId and score are null the array of objects should be like:

            [
                {
                    "roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
                    "teams": []
                },
                {
                    "roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
                    "teams": []
                },
                {
                    "roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
                    "teams": []
                }
            ]

If there are teamId and score for a roundId I have to return:

                    [
                        {
                            "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
                            "teams": [
                              { "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 21 },
                              { "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 20 },
                        },
                        {
                            "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
                            "teams": [
                              { "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 18 },
                              { "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 7 },
                        },
                        {
                            "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
                            "teams": [
                              { "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8", "score": 19 },
                              { "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0", "score": 12 },
                        }
                    ]

I tried that using reduce but I got it wrong:

const finalResult = matchesRoundsScore.reduce((result, currentValue) => {
            const foundRound = result.find(item => item.roundId === currentValue.roundId)
            if (!foundRound) {
                result.push({
                    roundId: currentValue.roundId,
                    teams: []
                })
            } else {
                result.push({
                    roundId: currentValue.roundId,
                    teams: new Array(currentValue.teamId, currentValue.score)
                })
            }
        }, [])

Thank you for your time! Let me know if something is unclear!

CodePudding user response:

This could be an option, using Map to merge records with same roundId

const merge = input => [...input.reduce((m, {roundId, teamId, score}) => {
  if (!m.has(roundId)) {
    m.set(roundId, []);
  }
  if (teamId) {
    m.get(roundId).push({teamId, score});
  }
  return m;
}, new Map())].map(([roundId, m]) => ({roundId, teams: [...m]}));

const input = [
                {
                    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
                    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
                    "score": 21
                },
                {
                    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
                    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
                    "score": 20
                },
                {
                    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
                    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
                    "score": 18
                },
                {
                    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
                    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
                    "score": 7
                },
                {
                    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
                    "teamId": null,
                    "score": null
                }
            ];

console.log(merge(input));

CodePudding user response:

Below is one possible way to achieve the target.

Code Snippet

// method to group data by "roundId"
const groupByRounds = arr => (
  // implict-return by extracting "values" of the intermediate result object
  Object.values(
    arr.reduce(                     // iterate using "reduce" to generate result-object
      (acc, {roundId, teamId, score}) => {        // de-structure to access props
        acc[roundId] = ({           // create/update value for key: "roundId"
          roundId,
          teams: (acc[roundId]?.teams ?? []).concat((
            teamId && score         // if "teamId" and "score" are both truthy
            ? [{ teamId, score }]   // add them to the array
            : []                    // else, it's an empty array
          ))
        })
        return acc;                 // "acc" is the accumulator / agrregator
      },
      {}                            // initial value of "acc" is empty object {}
    )
  )
);

const dataType0 = [{
    "roundId": "b382935b-fe84-4b8c-97e0-eb0b215c68c5",
    "teamId": null,
    "score": null
  },
  {
    "roundId": "d7f7d3be-cab0-45a6-965f-73f26eb39692",
    "teamId": null,
    "score": null
  },
  {
    "roundId": "f6aed9f1-5b8a-4da1-aeff-13620aee9c76",
    "teamId": null,
    "score": null
  }
];

const dataType1 = [{
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 21
  },
  {
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 20
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 18
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 7
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": null,
    "score": null
  }
];

const dataType2 = [{
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 21
  },
  {
    "roundId": "4fc1753a-38ca-4cd4-a772-620d86c35916",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 20
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 18
  },
  {
    "roundId": "62d0f2a1-be7a-4742-91bc-5a83cf408728",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 7
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": "fc6295c4-8527-4329-a3aa-373d854a04c8",
    "score": 19
  },
  {
    "roundId": "d600bdc1-dbd7-4683-9d20-581e4f759ccb",
    "teamId": "2e7fcc40-ac45-419b-a80d-a7713a5d6ce0",
    "score": 12
  }
];

console.log('data of type 0', groupByRounds(dataType0));
console.log('data of type 1', groupByRounds(dataType1));
console.log('data of type 2', groupByRounds(dataType2));
/*
console.log(
  'data of type combined',
  groupByRounds([
    ...dataType0, ...dataType1, ...dataType2
  ])
);
*/
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments added in the snippet above.

  • Related