I have an array of Objects with 4 keys:
[
{
"team": "USA",
"team_profile_id": "10",
"player": "Captain America",
"player_id": "10X1"
},
{
"team": "USA",
"team_profile_id": "10",
"player": "The hulk",
"player_id": "10X2"
},
{
"team": "India",
"team_profile_id": "20",
"player": "Captain America",
"player_id": "10X1"
},
{
"team": "India",
"team_profile_id": "20",
"player": "SpiderMan",
"player_id": "10X5"
}
]
And I want to group my array by "Teams" such that it creates an array of Player objects for each team
[
{
"team": "USA",
"team_profile_id": "10",
"Players": [
{
"player": "Captain America",
"player_id": "10X1"
},
{
"player": "The hulk",
"player_id": "10X2"
}
]
},
{
"team": "India",
"team_profile_id": "20",
"Players": [
{
"player": "Captain America",
"player_id": "10X1"
},
{
"player": "SpiderMan",
"player_id": "10x5"
}
]
}
]
I am currently trying to use reduce function from MDN prototype but it is not able to handle the sub object creation part.
Currently I have tried:
var group_to_values = result.reduce(function(obj, item) {
obj[item.team] = obj[item.team] || [];
obj[item.team].push({
"team_profile_id":item.team_profile_id,
"player":item.player,
"player_id":item.player_id
});
return obj;
}, {});
But it is not giving the desired result
Since the result needs to be an array you can use it as the initial value for reduce instead of an object:
var players = [ { "team": "USA", "team_profile_id": "10", "player": "Captain America", "player_id": "10X1" }, { "team": "USA", "team_profile_id": "10", "player": "The hulk", "player_id": "10X2" }, { "team": "India", "team_profile_id": "20", "player": "Captain America", "player_id": "10X1" }, { "team": "India", "team_profile_id": "20", "player": "SpiderMan", "player_id": "10X5" } ] var teams = players.reduce(function (teams, player) { var matchingTeams = teams.filter(function(team) { return team.team === player.team; }); var team; if (matchingTeams.length) { team = matchingTeams[0] } else { team = {} teams.push(team) } team.team = player.team; team.team_profile_id = player.team_profile_id; var teamPlayer = { player: player.player, player_id: player.player_id }; team.players = team.players ? team.players.concat(teamPlayer) : [teamPlayer]; return teams }, []) console.log(teams)
While you iterate the players with Array.reduce()
, destructure the player object, and separate between the player's properties, and team using spread.
If the team
doesn't exist in the accumulator ( r
), create a new object with the team's properties, and the Player: []
property. Push the players into the Players
array of the relevant team. Use Object.values()
to convert back to an array.
const data = [{"team":"USA","team_profile_id":"10","player":"Captain America","player_id":"10X1"},{"team":"USA","team_profile_id":"10","player":"The hulk","player_id":"10X2"},{"team":"India","team_profile_id":"20","player":"Captain America","player_id":"10X1"},{"team":"India","team_profile_id":"20","player":"SpiderMan","player_id":"10X5"}] const result = Object.values(data.reduce((r, { team, team_profile_id, ...player }) => { if(!r[team]) r[team] = { team, team_profile_id, Players: [] } r[team].Players.push(player) return r }, {})) console.log(result)
How to ES5 this solution:
Object.values()
, but we can generate a values()
functions using Object.keys()
.const
s with var
s, arrow functions with functions, destructuring with manual manual assignments. var data = [{"team":"USA","team_profile_id":"10","player":"Captain America","player_id":"10X1"},{"team":"USA","team_profile_id":"10","player":"The hulk","player_id":"10X2"},{"team":"India","team_profile_id":"20","player":"Captain America","player_id":"10X1"},{"team":"India","team_profile_id":"20","player":"SpiderMan","player_id":"10X5"}]; var result = values(data.reduce(function(r, o) { var team = o.team; if(!r[team]) r[team] = { team: team, team_profile_id: o.team_profile_id, Players: [] }; r[team].Players.push({ player: o.player, player_id: o.player_id }) return r }, {})) function values(obj) { return Object.keys(obj).map(function(key) { return obj[key]; }); } console.log(result)
You could find the object and add the new player.
var data = [{ team: "USA", team_profile_id: "10", player: "Captain America", player_id: "10X1" }, { team: "USA", team_profile_id: "10", player: "The hulk", player_id: "10X2" }, { team: "India", team_profile_id: "20", player: "Captain America", player_id: "10X1" }, { team: "India", team_profile_id: "20", player: "SpiderMan", player_id: "10X5" }], result = data.reduce((r, { team, team_profile_id, player, player_id }) => { var temp = r.find(q => q.team_profile_id === team_profile_id); if (!temp) r.push(temp = { team, team_profile_id, Players: [] }); temp.Players.push({ player, player_id }); return r; }, []); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is probably not the best way to do it but it works.
const players = [ { "team": "USA", "team_profile_id": "10", "player": "Captain America", "player_id": "10X1" }, { "team": "USA", "team_profile_id": "10", "player": "The hulk", "player_id": "10X2" }, { "team": "India", "team_profile_id": "20", "player": "Captain America", "player_id": "10X1" }, { "team": "India", "team_profile_id": "20", "player": "SpiderMan", "player_id": "10X5" } ] const teams = players.reduce((arr, player) => { let [team] = arr.filter(t => t.team === player.team) if (!team) { team = { team: player.team, team_profile_id: player.team_profile_id, Players: [] } arr.push(team) } team.Players.push({ player: player.player, player_id: player.player_id }) return arr }, []) console.log(teams)
Try the following. First I create a set of unique team names and then filter the data based on that to get a list of relevant players:
const data = [ { "team": "USA", "team_profile_id": "10", "player": "Captain America", "player_id": "10X1" }, { "team": "USA", "team_profile_id": "10", "player": "The hulk", "player_id": "10X2" }, { "team": "India", "team_profile_id": "20", "player": "Captain America", "player_id": "10X1" }, { "team": "India", "team_profile_id": "20", "player": "SpiderMan", "player_id": "10X5" } ]; const res = [...new Set(data.map(e => e.team))] .map(teamName => ({ team: teamName, team_profile_id: data.find(e => e.team === teamName).team_profile_id, Players: data .filter(p => p.team === teamName) .map(p => ({ player: p.player, player_id: p.player_id })) })); console.log(res);
Try this:
'use strict';
const inputData = [
{
"team": "USA",
"team_profile_id": "10",
"player": "Captain America",
"player_id": "10X1"
},
{
"team": "USA",
"team_profile_id": "10",
"player": "The hulk",
"player_id": "10X2"
},
{
"team": "India",
"team_profile_id": "20",
"player": "Captain America",
"player_id": "10X1"
},
{
"team": "India",
"team_profile_id": "20",
"player": "SpiderMan",
"player_id": "10X5"
}
];
function groupByTeams(data) {
// Find the teams
const teams = data.map(({ team }) => team);
const uniqueTeams = [...new Set(teams)];
// Map the array of unique values to return
// desired result.
return uniqueTeams.map(team => {
return {
team,
team_profile_id: data.find((thisTeam) => thisTeam.team === team).team_profile_id,
Players: data
.filter(thisTeam => thisTeam.team === team)
.map(({ player, player_id }) => ({ player_id, player }))
}
});
}
groupByTeams(inputData);
Try this...
const playerData = [ ... ]
const teamGroups = playerData.reduce ((teamData, playerObj) => {
const targetTeam = teamData.filter(t => t.team === playerObj.team)[0];
if (!targetTeam) {
return [ ...teamData, {
team: playerObj.team,
team_profile_id: playerObj.team_profile_id,
Players: [{
player: playerObj.player,
player_id: playerObj.player_id
}]
}];
}
targetTeam.Players.push ({ player: playerObj.player, player_id: playerObj.player_id });
return teamData;
}, []);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.