[英]Filter array of objects by comparing their properties
我试图在这个数组中找到一个对象的最高分,但结果不正确。 我们是否应该再次将分数重置为 0? 我试图将 score 变量放在obj[i.class]
下方,但没有任何改变:
function theScore (students) { var obj = {}; score = 0; for(i of students){ if(score < i.score) { obj[i.class] = { name: i.name, score: i.score }; }; }; return obj; }; console.log(theScore([ { name: 'Sara', score: 90, class: 'A' }, { name: 'Poyi', score: 85, class: 'B' }, { name: 'Adert', score: 74, class: 'A' }, { name: 'Shynta', score: 78, class: 'B' } ]));
期望的输出:
{
A: {
name: 'Sara',
score: 90
},
B: {
name: 'Poyi',
score: 85
}
}
你不能大量简化函数的 obj 赋值吗?
function theScore (students) {
var obj = {};
var score = 0;
for(i of students){
if(i.score > score ) {
score = i.score; // Keep track of the highest-score-found-so-far
obj = i; // Keep track of the highest scoring object
}
}
return obj;
}
找到最高分后,分数不会改变。 将分数更改为当前分数。 谢谢。 使用带有 index(Array) 的对象,而不是带有 map 的对象。 这应该有效。
function theScore (students) {
var obj = [];
score = 0;
for(i of students){
if(obj.length === 0) {
obj.push( i );
} else {
for( var x = 0; x < obj.length; x++ ){
if( i.score > obj[x].score ){
obj.splice( x, 0, i );
break;
}
}
if( x === obj.length ){
obj.push(i);
}
}
};
return obj;
};
console.log(theScore([
{
name: 'Sara',
score: 90,
class: 'A'
},
{
name: 'Poyi',
score: 85,
class: 'B'
},
{
name: 'Adert',
score: 74,
class: 'A'
},
{
name: 'Shynta',
score: 78,
class: 'B'
}
]));
你的代码的问题是你没有区分一个班级和另一个班级的学生分数。 当您找到更高的分数时,您也不会更新分数,因此每次循环运行时,每个学生的分数(除非它是 0)都将高于score
,并且您最终会得到列表中的最后一个分数。
编辑:编辑以显示如何仅使用一个循环来执行此操作
你需要:
function theScore (students) { const highScoresByClass = {}; const scores = {A: 0, B: 0, C: 0}; for (const student of students){ const classHighScore = scores[student.class]; if(classHighScore < student.score) { scores[student.class] = student.score; highScoresByClass[student.class] = { name: student.name, score: student.score }; }; }; return highScoresByClass; }; console.log(theScore([ { name: 'Sara', score: 90, class: 'A' }, { name: 'Poyi', score: 85, class: 'B' }, { name: 'Adert', score: 74, class: 'A' }, { name: 'Shynta', score: 78, class: 'B' } ]));
您需要跟踪已检查的classes
。
更Array.prototype.reduce
替代方法是使用函数Array.prototype.reduce
来构建所需的输出。 如您所见,基本上,这种方法是跟踪先前检查过的classes
。
function theScore (students) { return students.reduce((a, c) => { a[c.class] = (a[c.class] || (a[c.class] = c)); if (c.score > a[c.class].score) a[c.class] = c; return a; }, Object.create(null)); } console.log(theScore([ { name: 'Sara', score: 90, class: 'A' }, { name: 'Poyi', score: 85, class: 'B' }, { name: 'Adert', score: 74, class: 'A' }, { name: 'Shynta', score: 78, class: 'B' }]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
您的代码的问题实际上从未将实际对象分数进行比较,而是始终与 0 进行比较。
如果您真的想为此使用for in
循环,您可以执行以下操作(对代码稍作更改):
var data = [ { name: 'Sara', score: 90, class: 'A' }, { name: 'Poyi', score: 85, class: 'B' }, { name: 'Adert', score: 74, class: 'A' }, { name: 'Shynta', score: 78, class: 'B' } ] function theScore (students) { var obj = {} for(i of students){ if(!obj[i.class] || obj[i.class].score < i.score) { obj[i.class] = {name: i.name, score: i.score} } } return obj } console.log(theScore(data))
或者你可以使用reduce
并像这样解决它:
var data = [ { name: 'Sara', score: 90, class: 'A' }, { name: 'Poyi', score: 85, class: 'B' }, { name: 'Adert', score: 74, class: 'A' }, { name: 'Shynta', score: 78, class: 'B' } ] const maxByClass = (d) => d.reduce((r,{name, score, ...c}) => { r[c.class] = r[c.class] ? r[c.class].score > score ? r[c.class] : {name, score} : {name, score} return r }, {}) console.log(maxByClass(data))
由于reduce 返回一个累加器,我们只需要根据2 个类别中的哪一个分数较大并返回来分配正确的对象道具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.