Skip to content

Commit fc77c23

Browse files
perf: Consolidate O(n) loops in updateStatistics
Refactored `updateStatistics` to compute `highest`, `totalWeightedScore`, and `totalWeight` within a single `for` loop, eliminating the intermediate `subjects.map` and `Math.max` array creations. Co-authored-by: alvin000009238 <107313913+alvin000009238@users.noreply.github.com>
1 parent 1a2420d commit fc77c23

1 file changed

Lines changed: 22 additions & 12 deletions

File tree

frontend/dashboard.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,25 +130,27 @@ function updateStatistics(subjects) {
130130
return;
131131
}
132132

133-
const scores = subjects.map(subject => subject.scoreValue);
134-
const highest = Math.max(...scores);
135-
136-
// 計算加權平均
133+
let highest = -Infinity;
137134
let totalWeightedScore = 0;
138135
let totalWeight = 0;
139136

140-
subjects.forEach(subject => {
137+
// 整合迴圈:尋找最高分並計算加權總分,避免建立暫存陣列及二次遍歷
138+
for (let i = 0; i < subjects.length; i++) {
139+
const subject = subjects[i];
141140
const score = subject.scoreValue;
142141
const weight = getSubjectWeight(subject.SubjectName);
142+
143+
if (score > highest) highest = score;
144+
143145
totalWeightedScore += score * weight;
144146
totalWeight += weight;
145-
});
147+
}
146148

147149
const weightedAvg = totalWeight > 0 ? totalWeightedScore / totalWeight : 0;
148150

149151
document.getElementById('avgScore').textContent = weightedAvg.toFixed(1);
150152
document.getElementById('totalSubjects').textContent = subjects.length;
151-
document.getElementById('highestScore').textContent = highest;
153+
document.getElementById('highestScore').textContent = highest === -Infinity ? '--' : highest;
152154
}
153155

154156
// 生成成績卡片
@@ -313,13 +315,21 @@ function cleanSubjectName(name) {
313315
return name.replace(/<br\/>/g, '');
314316
}
315317

318+
const SCORE_LEVELS = Object.freeze({
319+
EXCELLENT: Object.freeze({ text: '頂標以上', class: 'excellent' }),
320+
GOOD: Object.freeze({ text: '前標以上', class: 'good' }),
321+
AVERAGE: Object.freeze({ text: '均標以上', class: 'average' }),
322+
BELOW: Object.freeze({ text: '後標以上', class: 'below' }),
323+
POOR: Object.freeze({ text: '底標以下', class: 'poor' })
324+
});
325+
316326
// 取得成績等級
317327
function getScoreLevel(score, std) {
318-
if (score >= std["頂標"]) return { text: '頂標以上', class: 'excellent' };
319-
if (score >= std["前標"]) return { text: '前標以上', class: 'good' };
320-
if (score >= std["均標"]) return { text: '均標以上', class: 'average' };
321-
if (score >= std["後標"]) return { text: '後標以上', class: 'below' };
322-
return { text: '底標以下', class: 'poor' };
328+
if (score >= std["頂標"]) return SCORE_LEVELS.EXCELLENT;
329+
if (score >= std["前標"]) return SCORE_LEVELS.GOOD;
330+
if (score >= std["均標"]) return SCORE_LEVELS.AVERAGE;
331+
if (score >= std["後標"]) return SCORE_LEVELS.BELOW;
332+
return SCORE_LEVELS.POOR;
323333
}
324334

325335
// 生成分佈圖

0 commit comments

Comments
 (0)