从 Javascript 数组派生计算数据
Derived Computed Data from Javascript Array
感谢您的帮助!我已经坚持了一段时间。
我有这个数组
students: [
{studentId: 'sss1', isAthlete: true, isHonors: true, testScore: 78, studentName: 'Bobby'},
{studentId: 'sss2', isAthlete: false, isHonors: false, testScore: 93, studentName: 'Sally'},
{studentId: 'sss3', isAthlete: true, isHonors: true, testScore: 82, studentName: 'Mikey'},
{studentId: 'sss4', isAthlete: false, isHonors: false, testScore: 88, studentName: 'Billy'},
{studentId: 'sss5', isAthlete: true, isHonors: false, testScore: 91, studentName: 'Davey'},
{studentId: 'sss6', isAthlete: false, isHonors: false, testScore: 94, studentName: 'Joey'},
{studentId: 'sss7', isAthlete: false, isHonors: true, testScore: 97, studentName: 'Nancy'},
{studentId: 'sss8', isAthlete: true, isHonors: false, testScore: 83, studentName: 'Susie'},
{studentId: 'sss9', isAthlete: false, isHonors: false, testScore: 72, studentName: 'Jimmy'},
]
上面的数组是使用reselect计算出来的,然后完美地注入到我的React组件中。
现在,在我的 React 组件中,我需要向我的用户展示:
Total Student Count: 9
Total Athlete Count: 4
Total Honors Count: 3
Average Overall Score: 86.44
Average Honors Score: 85.67
Average Athlete Score: 83.5
Highest Overall Student: Nancy
Highest Honors Student: Nancy
Highest Athlete Student: Davey
我的问题
1. 什么是 "best practice" for where 做这个计算?
2. 谁能想出一个数组方法来有效地进行这个计算?我的实际阵列有数百名学生。
不想在这里成为一个吃白食的人,但发现自己写了几十个这样的东西:
const athCount = students.filter(s => s.isAthlete === true).length
并且有那种我做错了的刺痛感。
谢谢你
- Can anyone dream up an array method to efficiently make this calculation? My actual array has hundreds of students.
您需要迭代数组。没有别的办法。但是,您可能只这样做一次:
let athletes = 0, honors = 0, honorScore = 0, athleteScore= 0, totalScore = 0, best = { score: 0 };
for(const student of students){
athletes += student.isAthlete;
honors += student.isHonors;
totalScore += student.score;
/*...*/
if(student.score > best.score)
best = student;
}
const data = [
{studentId: 'sss1', isAthlete: true, isHonors: true, testScore: 78, studentName: 'Bobby'},
{studentId: 'sss2', isAthlete: false, isHonors: false, testScore: 93, studentName: 'Sally'},
{studentId: 'sss3', isAthlete: true, isHonors: true, testScore: 82, studentName: 'Mikey'},
{studentId: 'sss4', isAthlete: false, isHonors: false, testScore: 88, studentName: 'Billy'},
{studentId: 'sss5', isAthlete: true, isHonors: false, testScore: 91, studentName: 'Davey'},
{studentId: 'sss6', isAthlete: false, isHonors: false, testScore: 94, studentName: 'Joey'},
{studentId: 'sss7', isAthlete: false, isHonors: true, testScore: 97, studentName: 'Nancy'},
{studentId: 'sss8', isAthlete: true, isHonors: false, testScore: 83, studentName: 'Susie'},
{studentId: 'sss9', isAthlete: false, isHonors: false, testScore: 72, studentName: 'Jimmy'},
]
const initialResult = {
count : {
athlete : 0,
honors : 0,
total : 0
},
accumulate : {
athlete : 0,
honors : 0,
total : 0
},
best : {
name : null,
score : null
}
};
const result = data.reduce(process, initialResult);
function process (result, record) {
result.count.total++;
result.accumulate.total += record.testScore;
if (record.isAthlete) {
result.count.athlete++;
result.accumulate.athlete += record.testScore;
}
if (record.isHonors) {
result.count.honors++;
result.accumulate.honors += record.testScore;
}
let best = result.best;
if (best.name === null && best.score === null) {
best.name = record.studentName;
best.score = record.testScore;
} else {
if (best.score < record.testScore) {
best.name = record.studentName;
best.score = record.testScore;
}
}
return result;
}
console.log(result);
答案1:在不知道输入数据变化频率的情况下,我认为你应该把所有的计算都放在render
函数中。这样,DOM 始终与数据一致。在大多数情况下,这会工作得很好,您不会注意到任何性能影响。
答案 2:在这个例子中,_
是 lodash
package。
const athletes = students.filter(({isAthlete}) => isAthlete);
const athleteCount = athletes.length;
const averageScore = _.sumBy(students, 'testScore') / students.length;
const averageHonorsScore = _.sumBy(athletes, 'testScore') / students.length;
const highestSCore = _.maxBy(students, 'testScore')
const highestAthleteScore = _.maxBy(athletes, 'testScore');
感谢您的帮助!我已经坚持了一段时间。
我有这个数组
students: [
{studentId: 'sss1', isAthlete: true, isHonors: true, testScore: 78, studentName: 'Bobby'},
{studentId: 'sss2', isAthlete: false, isHonors: false, testScore: 93, studentName: 'Sally'},
{studentId: 'sss3', isAthlete: true, isHonors: true, testScore: 82, studentName: 'Mikey'},
{studentId: 'sss4', isAthlete: false, isHonors: false, testScore: 88, studentName: 'Billy'},
{studentId: 'sss5', isAthlete: true, isHonors: false, testScore: 91, studentName: 'Davey'},
{studentId: 'sss6', isAthlete: false, isHonors: false, testScore: 94, studentName: 'Joey'},
{studentId: 'sss7', isAthlete: false, isHonors: true, testScore: 97, studentName: 'Nancy'},
{studentId: 'sss8', isAthlete: true, isHonors: false, testScore: 83, studentName: 'Susie'},
{studentId: 'sss9', isAthlete: false, isHonors: false, testScore: 72, studentName: 'Jimmy'},
]
上面的数组是使用reselect计算出来的,然后完美地注入到我的React组件中。
现在,在我的 React 组件中,我需要向我的用户展示:
Total Student Count: 9
Total Athlete Count: 4
Total Honors Count: 3
Average Overall Score: 86.44
Average Honors Score: 85.67
Average Athlete Score: 83.5
Highest Overall Student: Nancy
Highest Honors Student: Nancy
Highest Athlete Student: Davey
我的问题
1. 什么是 "best practice" for where 做这个计算?
2. 谁能想出一个数组方法来有效地进行这个计算?我的实际阵列有数百名学生。
不想在这里成为一个吃白食的人,但发现自己写了几十个这样的东西:
const athCount = students.filter(s => s.isAthlete === true).length
并且有那种我做错了的刺痛感。
谢谢你
- Can anyone dream up an array method to efficiently make this calculation? My actual array has hundreds of students.
您需要迭代数组。没有别的办法。但是,您可能只这样做一次:
let athletes = 0, honors = 0, honorScore = 0, athleteScore= 0, totalScore = 0, best = { score: 0 };
for(const student of students){
athletes += student.isAthlete;
honors += student.isHonors;
totalScore += student.score;
/*...*/
if(student.score > best.score)
best = student;
}
const data = [
{studentId: 'sss1', isAthlete: true, isHonors: true, testScore: 78, studentName: 'Bobby'},
{studentId: 'sss2', isAthlete: false, isHonors: false, testScore: 93, studentName: 'Sally'},
{studentId: 'sss3', isAthlete: true, isHonors: true, testScore: 82, studentName: 'Mikey'},
{studentId: 'sss4', isAthlete: false, isHonors: false, testScore: 88, studentName: 'Billy'},
{studentId: 'sss5', isAthlete: true, isHonors: false, testScore: 91, studentName: 'Davey'},
{studentId: 'sss6', isAthlete: false, isHonors: false, testScore: 94, studentName: 'Joey'},
{studentId: 'sss7', isAthlete: false, isHonors: true, testScore: 97, studentName: 'Nancy'},
{studentId: 'sss8', isAthlete: true, isHonors: false, testScore: 83, studentName: 'Susie'},
{studentId: 'sss9', isAthlete: false, isHonors: false, testScore: 72, studentName: 'Jimmy'},
]
const initialResult = {
count : {
athlete : 0,
honors : 0,
total : 0
},
accumulate : {
athlete : 0,
honors : 0,
total : 0
},
best : {
name : null,
score : null
}
};
const result = data.reduce(process, initialResult);
function process (result, record) {
result.count.total++;
result.accumulate.total += record.testScore;
if (record.isAthlete) {
result.count.athlete++;
result.accumulate.athlete += record.testScore;
}
if (record.isHonors) {
result.count.honors++;
result.accumulate.honors += record.testScore;
}
let best = result.best;
if (best.name === null && best.score === null) {
best.name = record.studentName;
best.score = record.testScore;
} else {
if (best.score < record.testScore) {
best.name = record.studentName;
best.score = record.testScore;
}
}
return result;
}
console.log(result);
答案1:在不知道输入数据变化频率的情况下,我认为你应该把所有的计算都放在render
函数中。这样,DOM 始终与数据一致。在大多数情况下,这会工作得很好,您不会注意到任何性能影响。
答案 2:在这个例子中,_
是 lodash
package。
const athletes = students.filter(({isAthlete}) => isAthlete);
const athleteCount = athletes.length;
const averageScore = _.sumBy(students, 'testScore') / students.length;
const averageHonorsScore = _.sumBy(athletes, 'testScore') / students.length;
const highestSCore = _.maxBy(students, 'testScore')
const highestAthleteScore = _.maxBy(athletes, 'testScore');