Home > Blockchain >  Group array by multiple keys and change keys name JavaScript
Group array by multiple keys and change keys name JavaScript

Time:04-12

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!

CodePudding user response:

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

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

    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)

CodePudding user response:

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}

CodePudding user response:

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"}];

getPlayer = (targetUserId) => {
    const { username, image_url } = data.find(({ userId }) => userId === targetUserId);
    return { id: targetUserId, username, imageURL: image_url };
};

getPlayers = (targetTeamId) =>  { 
  const [firstPlayer, secondPlayer] = data
      .filter(({ teamId }) => teamId === targetTeamId)
      .map(({ userId }) => getPlayer(userId));
  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; }

  • Related