0

I have an array of objects:

[
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '0745ad6f-7cfb-4d31-864a-55c1c47517ab',
    name: '[email protected] & [email protected]',
    userId: '0abe5edf-4d11-4edf-869f-d662497b95a9',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/1cbca5e505e7f8278034868b74304f03?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '0745ad6f-7cfb-4d31-864a-55c1c47517ab',
    name: '[email protected] & [email protected]',
    userId: '16dd8334-610e-4f03-893a-e5dfc7cdbf68',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/d219af79b45e5891507fda4c4c2139a0?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '653e2a5d-8d5d-405b-8d2c-75adccfafbb4',
    name: '[email protected] & [email protected]',
    userId: 'b12ffed0-198d-4c0e-ba74-b08674dd0f30',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/e8b9531d711b33d5de588e30373df98c?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '653e2a5d-8d5d-405b-8d2c-75adccfafbb4',
    name: '[email protected] & [email protected]',
    userId: 'e5550fae-125f-4a3b-b471-b0e17137ed3c',
    username: '[email protected]',
    image_url: 'string'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'aa98f822-b4c9-480c-ab31-d08245f8409c',
    name: '[email protected] & [email protected]',
    userId: '7e590328-dd17-4f20-8475-cff41d5f78db',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/0a7bacc193aadc85cca225742fb23b59?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'aa98f822-b4c9-480c-ab31-d08245f8409c',
    name: '[email protected] & [email protected]',
    userId: '5eb9d5f0-4d1b-444c-b115-2a9c16a33403',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/01f74db6c7c09ab82daa12c02b3f06f6?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'c242019b-9565-4a87-9b52-46f45b4421c8',
    name: '[email protected] & [email protected]',
    userId: 'af26d521-26b8-4fe6-93fa-cc44abcf4211',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/8ae4d2bd972405fcbe19f89428f51ad7?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'c242019b-9565-4a87-9b52-46f45b4421c8',
    name: '[email protected] & [email protected]',
    userId: '89f1b2e9-7c49-4831-a461-4584674ca963',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/db02726a3f9015d4434f32092ee08f0c?d=wavatar'
  }
]

I want to group this array of objects based on similar keys, but I want to change the name of the keys because my final response should look like this:

[
  {
    "id": "matchId",
    "firstTeam": {
      "id": "teamId",
      "name": "name",
      "firstPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      },
      "secondPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      }
    },
    "secondTeam": {
      "id": "teamId",
      "name": "name",
      "firstPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      },
      "secondPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      }
    }
  },
  {
    "id": "matchId",
    "firstTeam": {
      "id": "teamId",
      "name": "name",
      "firstPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      },
      "secondPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      }
    },
    "secondTeam": {
      "id": "teamId",
      "name": "name",
      "firstPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      },
      "secondPlayer": {
        "id": "userId",
        "username": "username",
        "imageURL": "image_url"
      }
    }
  }
]

As you can see in the initial array, there is an object for every player, which two players stays in a team and a match is consisted by two teams.

I tried using reduce but what it gets me, it's the changing name of the keys (of course it didn't work):

const finalResult = result.reduce((previousValue, currentValue) => {
                previousValue[currentValue.matchId] = previousValue[currentValue.matchId] || []
                previousValue.matchId = currentValue.matchId
                previousValue.firstTeam = {
                    id: currentValue.teamId,
                    name: currentValue.name,
                    firstPlayer: {
                        id: currentValue.userId,
                        username: currentValue.username,
                        imageURL: currentValue.image_url
                    },
                    secondPlayer: {
                        id: currentValue.userId,
                        username: currentValue.username,
                        imageURL: currentValue.image_url
                    }
                }

                return currentValue
            }, Object.create(null))

Is there any way I can do this using reduce? Or any other method

Thank you for your time!

4
  • You say, you want an array as outcome, yet you put in an object was initial value for reduce (and will therefore also get an object back). So what is it, you really want? Commented Apr 12, 2022 at 6:49
  • @derpirscher both my initial data and my expected data are an array of objects. But based on my initial data I have to create some nested objects, and finally will also be an array of objects Commented Apr 12, 2022 at 6:51
  • With Object.create(null) you are passing an object to reduce (as previousValue). And you are returning also this previousValue Thus you get back an object Commented Apr 12, 2022 at 6:53
  • Yes, my bad with that previousValue instead of currentValue Commented Apr 12, 2022 at 6:56

3 Answers 3

1

You can check the below implementation with reduce

const finalResult = data.reduce((result, currentValue) => {
  const foundMatch = result.find(item => item.id === currentValue.matchId)
  if (!foundMatch) {
    //add a new match with a new team along with the first player
    result.push({
      id: currentValue.matchId,
      firstTeam: createTeam(currentValue),
    })
  } else {
    if (foundMatch.firstTeam.id === currentValue.teamId) {
      //create the second player in the first team
      foundMatch.firstTeam.secondPlayer = createPlayer(currentValue)
      return result
    }

    if (!foundMatch.secondTeam) {
      //create the second team along with the first player
      foundMatch.secondTeam = createTeam(currentValue)
    } else {
      //create the second player in the second team
      foundMatch.secondTeam.secondPlayer = createPlayer(currentValue)
    }
  }

  return result
}, [])

Full integration

const data = [{
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '0745ad6f-7cfb-4d31-864a-55c1c47517ab',
    name: '[email protected] & [email protected]',
    userId: '0abe5edf-4d11-4edf-869f-d662497b95a9',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/1cbca5e505e7f8278034868b74304f03?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '0745ad6f-7cfb-4d31-864a-55c1c47517ab',
    name: '[email protected] & [email protected]',
    userId: '16dd8334-610e-4f03-893a-e5dfc7cdbf68',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/d219af79b45e5891507fda4c4c2139a0?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '653e2a5d-8d5d-405b-8d2c-75adccfafbb4',
    name: '[email protected] & [email protected]',
    userId: 'b12ffed0-198d-4c0e-ba74-b08674dd0f30',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/e8b9531d711b33d5de588e30373df98c?d=wavatar'
  },
  {
    matchId: 'f9120918-d2bf-4f5a-ab03-82fdeca9770f',
    teamId: '653e2a5d-8d5d-405b-8d2c-75adccfafbb4',
    name: '[email protected] & [email protected]',
    userId: 'e5550fae-125f-4a3b-b471-b0e17137ed3c',
    username: '[email protected]',
    image_url: 'string'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'aa98f822-b4c9-480c-ab31-d08245f8409c',
    name: '[email protected] & [email protected]',
    userId: '7e590328-dd17-4f20-8475-cff41d5f78db',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/0a7bacc193aadc85cca225742fb23b59?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'aa98f822-b4c9-480c-ab31-d08245f8409c',
    name: '[email protected] & [email protected]',
    userId: '5eb9d5f0-4d1b-444c-b115-2a9c16a33403',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/01f74db6c7c09ab82daa12c02b3f06f6?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'c242019b-9565-4a87-9b52-46f45b4421c8',
    name: '[email protected] & [email protected]',
    userId: 'af26d521-26b8-4fe6-93fa-cc44abcf4211',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/8ae4d2bd972405fcbe19f89428f51ad7?d=wavatar'
  },
  {
    matchId: 'c902a62a-0f33-45ad-9e2e-596bf91f3a9c',
    teamId: 'c242019b-9565-4a87-9b52-46f45b4421c8',
    name: '[email protected] & [email protected]',
    userId: '89f1b2e9-7c49-4831-a461-4584674ca963',
    username: '[email protected]',
    image_url: 'https://www.gravatar.com/avatar/db02726a3f9015d4434f32092ee08f0c?d=wavatar'
  }
]

const createPlayer = ({
  userId,
  username,
  image_url
}) => {
  return {
    "id": userId,
    "username": username,
    "imageURL": image_url
  }
}

const createTeam = ({
  teamId,
  name,
  ...otherData
}) => {
  return {
    id: teamId,
    name: name,
    firstPlayer: createPlayer(otherData)
  }
}

const finalResult = data.reduce((result, currentValue) => {
  const foundMatch = result.find(item => item.id === currentValue.matchId)
  if (!foundMatch) {
    //add a new match with a new team along with the first player
    result.push({
      id: currentValue.matchId,
      firstTeam: createTeam(currentValue),
    })
  } else {
    if (foundMatch.firstTeam.id === currentValue.teamId) {
      //create the second player in the first team
      foundMatch.firstTeam.secondPlayer = createPlayer(currentValue)
      return result
    }

    if (!foundMatch.secondTeam) {
      //create the second team along with the first player
      foundMatch.secondTeam = createTeam(currentValue)
    } else {
      //create the second player in the second team
      foundMatch.secondTeam.secondPlayer = createPlayer(currentValue)
    }
  }

  return result
}, [])

console.log(finalResult)

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

1 Comment

it has a tiny bug there foundMatch.firstTeam.id === currentValue.teamId needs to call return result @poPaTheGuru
1

Here is one way of doing it:

const da=[{ matchId: 'm1', teamId: 't1', name: 'tn1', userId: 'u1', username: 'un1', image_url: 'https://www.gravatar.com/avatar/u1'},
{matchId: 'm1', teamId: 't1', name: 'tn1', userId: 'u2', username: 'un2', image_url: 'https://www.gravatar.com/avatar/u2'},
{matchId: 'm1', teamId: 't2', name: 'tn2', userId: 'u3', username: 'un3', image_url: 'https://www.gravatar.com/avatar/u3'},
{matchId: 'm1', teamId: 't2', name: 'tn2', userId: 'u4', username: 'un4', image_url: 'string'},
{matchId: 'm2', teamId: 't3', name: 'tn3', userId: 'u5', username: 'un3', image_url: 'https://www.gravatar.com/avatar/u5'},
{matchId: 'm2', teamId: 't3', name: 'tn3', userId: 'u6', username: 'un5', image_url: 'https://www.gravatar.com/avatar/u6'},
{matchId: 'm2', teamId: 't4', name: 'tn4', userId: 'u7', username: 'un6', image_url: 'https://www.gravatar.com/avatar/u7'},
{matchId: 'm2', teamId: 't4', name: 'tn4', userId: 'u8', username: 'un7', image_url: 'https://www.gravatar.com/avatar/u8'}];


const res=Object.values(da.reduce((a, c) => {
  let m = a[c.matchId];
  if (!m) {
    m = a[c.matchId] = {
      matchId: c.matchId,
      firstTeam: {
        id: c.teamId,
        name: c.name,
        firstPlayer: {
          id: c.userId,
          username: c.username,
          imageurl: c.image_url
        }
      },
      secondTeam: {}
    };
  } else {
   let t = m.firstTeam.id===c.teamId ? m.firstTeam : m.secondTeam;
   if (!t.id) {t.id=c.teamId; t.name=c.name;}   
   t[!t.firstPlayer ? "firstPlayer" : "secondPlayer"] = 
     {id: c.userId, username: c.username, imageurl:c.image_url};
  }
  return a;
}, {}));

console.log(res)
.as-console-wrapper {max-height:100% !important}

1 Comment

I had to retract my solution at first because of a silly mistake. Here it is again, corrected.
1

Another way, a kind of request-response approach:

const data=[{matchId:"f9120918-d2bf-4f5a-ab03-82fdeca9770f",teamId:"0745ad6f-7cfb-4d31-864a-55c1c47517ab",name:"[email protected] & [email protected]",userId:"0abe5edf-4d11-4edf-869f-d662497b95a9",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/1cbca5e505e7f8278034868b74304f03?d=wavatar"},{matchId:"f9120918-d2bf-4f5a-ab03-82fdeca9770f",teamId:"0745ad6f-7cfb-4d31-864a-55c1c47517ab",name:"[email protected] & [email protected]",userId:"16dd8334-610e-4f03-893a-e5dfc7cdbf68",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/d219af79b45e5891507fda4c4c2139a0?d=wavatar"},{matchId:"f9120918-d2bf-4f5a-ab03-82fdeca9770f",teamId:"653e2a5d-8d5d-405b-8d2c-75adccfafbb4",name:"[email protected] & [email protected]",userId:"b12ffed0-198d-4c0e-ba74-b08674dd0f30",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/e8b9531d711b33d5de588e30373df98c?d=wavatar"},{matchId:"f9120918-d2bf-4f5a-ab03-82fdeca9770f",teamId:"653e2a5d-8d5d-405b-8d2c-75adccfafbb4",name:"[email protected] & [email protected]",userId:"e5550fae-125f-4a3b-b471-b0e17137ed3c",username:"[email protected]",image_url:"string"},{matchId:"c902a62a-0f33-45ad-9e2e-596bf91f3a9c",teamId:"aa98f822-b4c9-480c-ab31-d08245f8409c",name:"[email protected] & [email protected]",userId:"7e590328-dd17-4f20-8475-cff41d5f78db",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/0a7bacc193aadc85cca225742fb23b59?d=wavatar"},{matchId:"c902a62a-0f33-45ad-9e2e-596bf91f3a9c",teamId:"aa98f822-b4c9-480c-ab31-d08245f8409c",name:"[email protected] & [email protected]",userId:"5eb9d5f0-4d1b-444c-b115-2a9c16a33403",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/01f74db6c7c09ab82daa12c02b3f06f6?d=wavatar"},{matchId:"c902a62a-0f33-45ad-9e2e-596bf91f3a9c",teamId:"c242019b-9565-4a87-9b52-46f45b4421c8",name:"[email protected] & [email protected]",userId:"af26d521-26b8-4fe6-93fa-cc44abcf4211",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/8ae4d2bd972405fcbe19f89428f51ad7?d=wavatar"},{matchId:"c902a62a-0f33-45ad-9e2e-596bf91f3a9c",teamId:"c242019b-9565-4a87-9b52-46f45b4421c8",name:"[email protected] & [email protected]",userId:"89f1b2e9-7c49-4831-a461-4584674ca963",username:"[email protected]",image_url:"https://www.gravatar.com/avatar/db02726a3f9015d4434f32092ee08f0c?d=wavatar"}];

getPlayers = (targetTeamId) =>  { 
    const getPlayer = ({ targetUserId, username, image_url }) => 
    ({ id: targetUserId, username, imageURL: image_url });
    
    const [firstPlayer, secondPlayer] = data
        .filter(({ teamId }) => teamId === targetTeamId)
        .map((item) => getPlayer(item));
    return { firstPlayer, secondPlayer };  
};

getTeam = (targetTeamId) => ({
     id: targetTeamId, 
     name: data.find(({ teamId }) => teamId === targetTeamId).name, 
     ...getPlayers(targetTeamId),
});

getTeams = (targetMatchId) => {
    const teamIds =  [...new Set(data
        .filter(({ matchId }) => matchId === targetMatchId)
        .map(({ teamId }) => teamId))];
    const [firstTeam, secondTeam] = teamIds.map((teamId) => getTeam(teamId));
    return { firstTeam, secondTeam };
};

getMatch = (targetMatch) => ({ id: targetMatch, ...getTeams(targetMatch) });

getMatches = () => {
    const matchIds =  [...new Set(data.map(({ matchId }) => matchId))];
    return matchIds.map((matchId) => getMatch(matchId));
};

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

Comments

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.