0

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!

2 Answers 2

2

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));

Sign up to request clarification or add additional context in comments.

2 Comments

I was trying so hard to use reduce that i forgot i can add some mapping in it. Thank you
It's good to use map if the array is large.
1

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.

1 Comment

Thank you for enlighten me with this reduce solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.