我正在尝试过滤对象数组。我可以根据自己的情况进行过滤并获得结果,但是我想在过滤后采取措施。
heroes = [
//match1
{
player1: { name: "Batman", score: 1},
player2: { name: "Ironman", score: 3}
},
//match2
{
player1: { name: "Thor", score: 0},
player2: { name: "Superman", score: 2}
},
//match3
{
player1: { name: "Superman", score: 4},
player2: { name: "Batman", score: 1}
},
//match4
{
player1: { name: "Ironman", score: 3},
player2: { name: "Thor", score: 5}
}
];
我正在提供示例方案。例如,我想计算所有比赛中蝙蝠侠的总得分。但是正如您所看到的,蝙蝠侠有时是玩家1,有时是玩家2。
这就是为什么我发现这样的原因:
//While Batman player1, find all matches and sum scores
var player1matches = heroes.filter(match => match.player1.name.indexOf("Batman") > -1);
var player1scores= player1matches .reduce(((acc, match) => acc + match.player1.score), 0);
//While Batman player2, find all matches and sum scores
var player2matches = heroes.filter(match => match.player2.name.indexOf("Batman") > -1);
var player2scores= player1matches .reduce(((acc, match) => acc + match.player2.score), 0);
//Total Batman scores
var batmanScore = player1scores+ player2scores
但这肯定不是一个好的解决方案,因为player1对象中将有很多道具,而我将使用这些数据。
简而言之,我在player1和player2对象中有很多道具。我想根据特定名称对这些数据求和/订阅/计数。
等待您的建议。
答案 0 :(得分:1)
老实说,这个问题有点令人困惑,但是按照您所说的,这是一个解决方案。另外,我相信您的数组声明不正确,如果您想要匹配的数组,请尝试以下操作:
matches = [
{
player1: { name: "Batman", score: 1},
player2: { name: "Ironman", score: 3}
},
{
player1: { name: "Thor", score: 0},
player2: { name: "Superman", score: 2}
},
{
player1: { name: "Superman", score: 4},
player2: { name: "Batman", score: 1}
},
{
player1: { name: "Ironman", score: 3},
player2: { name: "Thor", score: 5}
}
];
然后,您可以进行比赛,并且如果其中任一球员为batman
,请创建一个总和并将其积分加到其中。
var batmanTotalPoints = 0;
heroes.forEach(function(match) {
if(match.player1.name === 'Batman') batmanTotalPoints += match.player1.score;
else if (match.player2.name === 'Batman') batmanTotalPoints += match.player2.score;
})
但是这里所有其他答案也将非常有效!使用reduce
也是一个不错的选择。
答案 1 :(得分:1)
您可以直接减少数组以获得最终分数。
function calculateScoreForPlayer(heroes, playerName){
return heroes.reduce( (result, currentHero) => {
const p1 = currentHero.player1;
const p2 = currentHero.player2;
if(p1.name === playerName){
result.score += p1.score;
}
if(p2.name === playerName){
result.score += p2.score;
}
return result;
} , { score : 0}).score;
}
编辑:要从评论中回答问题
原始答案只是做事的一个简短方法
function calculateScoreForPlayer(heroes, playerName) {
const result = heroes.reduce(
(result, currentHero) => {
const p1 = currentHero.player1;
const p2 = currentHero.player2;
if (p1.name === playerName) {
result.score += p1.score;
}
if (p2.name === playerName) {
result.score += p2.score;
}
return result;
}, { score: 0 });
return result.score;
}
我没有将结果存储在临时变量result
中,而是返回了实际对象。
假设输出得分为3,那么如果您不做.score
部分,则会得到一个对象{ score: 3 }
如果您这样做.score
,则会得到3
作为输出。
希望有帮助
答案 2 :(得分:0)
对于每场比赛,我们都会检查每位球员。对于每个玩家,我们执行以下两项操作之一:
然后我们获得每场比赛的总和。然后,我们得到所有匹配项的总和。这样就得出了该名称的总得分。
heroes = [
match1 = {
player1: { name: "Batman", score: 1},
player2: { name: "Ironman", score: 3}
},
match2 = {
player1: { name: "Thor", score: 0},
player2: { name: "Superman", score: 2}
},
match3 = {
player1: { name: "Superman", score: 4},
player2: { name: "Batman", score: 1}
},
match4 = {
player1: { name: "Ironman", score: 3},
player2: { name: "Thor", score: 5}
}
];
const getNameScore = (input, name) => input
.map(match => Object.keys(match)
.map(key => match[key].name === name ?
match[key].score : 0
).reduce((prev, curr) => prev + curr, 0)
).reduce((prev, curr) => prev + curr, 0)
console.dir(getNameScore(heroes, "Ironman"))
console.dir(getNameScore(heroes, "Batman"))
console.dir(getNameScore(heroes, "Thor"))
答案 3 :(得分:0)
function getScore(name) {
return heroes.map(x => { //Map each match to either a score or NULL
if (x.player1.name === name) return x.player1.score;
if (x.player2.name === name) return x.player2.score;
return null;
})
.filter(x => null !== x) //Remove NULL
.reduce((acc, current) => acc + current); //Sum
}
console.log(getScore('Superman')); // => 6
console.log(getScore('Batman')); // => 2
console.log(getScore('Thor')); // => 5
在此示例中,我们将每个匹配项映射到得分(整数)或 NULL 。之后,我们通过过滤来删除所有NULL值,然后通过将它们加在一起将它们减小为单个整数。这给了我们最后一个整数-总分。
答案 4 :(得分:0)
我可以建议一个幼稚的解决方案,因为它无效,因此您可以重构提议的数组。 这是一个工作示例:
// it's actually matchs and not heroes
// at least for me :)
matchs = [
// match 1
[{
name: "Batman",
score: 1
}, // player 1
{
name: "Ironman",
score: 3
}
], // player 2
// match 2
[{
name: "Thor",
score: 0
}, // player 1
{
name: "Superman",
score: 2
}
], // player 2
// match 3
[{
name: "Superman",
score: 4
}, // player 1
{
name: "Batman",
score: 1
}
], // player 2
// match 4
[{
name: "Ironman",
score: 3
}, // player 1
{
name: "Thor",
score: 5
}
], // player 2
]
function heroScore(name) {
let score = 0;
// loop through matchs
matchs.forEach(match => {
if (match[0].name === name ||
match[1].name === name) {
score += match[0].name === name ? match[0].score : match[1].score;
}
});
return score;
}
console.log("Batman : " + heroScore("Batman"));
console.log("Thor : " + heroScore("Thor"));
console.log("Superman : " + heroScore("Superman"));
console.log("Ironman : " + heroScore("Ironman"));
此解决方案效率不高,因为它会解析``匹配''数组中的每个元素,如果数组太长,则可能会消耗资源;
答案 5 :(得分:0)
您有很多选择,但是如果您需要其他属性,则可能需要修改数据结构:
let matches = getData();
//create a new player and match key for each player and only an array of players
let flattened = []
matches.forEach((match,match_num)=>{
for(let player in match){
let new_player = Object.assign({},match[player]);
new_player.player = player;
new_player.match = match_num+1;
flattened.push(new_player)
}
});
console.log('flattened:\n',flattened);
// Batman
const batman = flattened.filter(player=>player.name.toLowerCase()=='batman')
console.log('batman:\n',batman);
// Sums
const scores = flattened.reduce((acc,player)=>{
if (typeof acc[player.name] == 'undefined')
acc[player.name]=0;
acc[player.name] += +player.score;
return acc;
},{});
console.log('scores:\n', scores);
function getData() {
return [
//match1
{
player1: {
name: "Batman",
score: 1
},
player2: {
name: "Ironman",
score: 3
}
},
//match2
{
player1: {
name: "Thor",
score: 0
},
player2: {
name: "Superman",
score: 2
}
},
//match3
{
player1: {
name: "Superman",
score: 4
},
player2: {
name: "Batman",
score: 1
}
},
//match4
{
player1: {
name: "Ironman",
score: 3
},
player2: {
name: "Thor",
score: 5
}
}
];
}