我有一个带有 4 个键的对象数组:
[
{
"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"
}
]
我想按"团队"对我的数组进行分组,以便为每个团队创建一个 Player 对象数组
[
{
"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"
}
]
}
]
我目前正在尝试使用 MDN 原型中的 reduce 函数,但它无法处理子对象创建部分。
目前我已经尝试过:
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;
}, {});
但它没有给出预期的结果
由于结果需要是一个数组,因此您可以将其用作reduce的初始值而不是对象:
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)
您可以找到对象并添加新播放器。
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; }
当您使用Array.reduce()
迭代玩家时,解构玩家对象,并使用 spread 在玩家的属性和团队之间分离。
如果累加器(r
(中不存在team
,则创建一个包含团队属性和Player: []
属性的新对象。将玩家推入相关团队的Players
阵列中。使用Object.values()
转换回数组。
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)
如何ES5此解决方案:
- 主要问题是
Object.values()
,但是我们可以使用Object.keys()
生成一个values()
函数。 - 将
const
替换为var
s,将箭头函数替换为函数,将解构替换为手动手动分配。
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)
这可能不是最好的方法,但它有效。
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)
请尝试以下操作。首先,我创建一组唯一的团队名称,然后基于该名称过滤数据以获取相关球员的列表:
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);
试试这个:
'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);
试试这个...
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;
}, []);