如何对CSV处理后的JSON按economy排序提取年度Top10投手?
投手数据排序过滤与格式转换实现
问题背景
现有Node.js代码已完成matches.csv和deliveries.csv的数据合并,生成按赛季分组的投手统计对象,但需完成以下需求:
- 每个赛季的投手按
economy(经济值,数值越小表现越好)升序排序 - 提取每个赛季排序后的前10名投手
- 将每个赛季的对象结构转换为指定的数组格式
修改后完整代码
const csv = require('csv-parser') const fs = require('fs') let matchesData = {} let innData = [] let convertedObject = {} function convertIntoObject(){ for (let i = 0; i < innData.length; i++) { const season = innData[i].SEASON const bowler = innData[i].BOWLER if(!convertedObject[season]){ convertedObject[season] = {} } if(!convertedObject[season][bowler]){ convertedObject[season][bowler] = { totalRuns: 0, balls: 0, economy: 0 } } // 计算实际失分数(排除bye和legbye) const actualRuns = innData[i].TOTAL_RUNS - innData[i].BYE_RUNS - innData[i].LEGBYE_RUNS // 更新总失分数和投球数 const updatedTotalRuns = Number(convertedObject[season][bowler].totalRuns) + Number(actualRuns) const updatedBalls = Number(convertedObject[season][bowler].balls) + 1 // 计算经济值(避免除以0) const economy = updatedBalls > 0 ? (updatedTotalRuns / (updatedBalls / 6)).toFixed(2) : 0 convertedObject[season][bowler] = { totalRuns: updatedTotalRuns, balls: updatedBalls, economy: economy } } } // 处理最终数据:排序、取前10、转换格式 function processFinalData() { const result = {} // 遍历每个赛季数据 Object.keys(convertedObject).forEach(season => { const bowlers = convertedObject[season] // 将投手对象转为键值对数组,方便排序 const bowlerEntries = Object.entries(bowlers).map(([name, stats]) => ({ name, stats })) // 按economy升序排序(转为浮点数避免字符串排序错误) bowlerEntries.sort((a, b) => parseFloat(a.stats.economy) - parseFloat(b.stats.economy)) // 截取前10名并转换为目标格式 const top10Bowlers = bowlerEntries.slice(0, 10).map(item => ({ [item.name]: item.stats })) result[season] = top10Bowlers }) return result } // 确保matches.csv加载完成后再处理deliveries.csv fs.createReadStream('matches.csv') .pipe(csv()) .on('data', (data) => { matchesData[data.MATCH_ID] = data.SEASON }) .on('end', () => { fs.createReadStream('deliveries.csv') .pipe(csv()) .on('data', (data) => { innData.push({...data, "SEASON": matchesData[data.MATCH_ID]}) }) .on('end', () => { convertIntoObject() const finalResult = processFinalData() fs.writeFileSync("output.txt", JSON.stringify(finalResult, null, 2)) }) });
关键逻辑说明
- 数据依赖修复:将
deliveries.csv的读取嵌套在matches.csv的end事件内,避免因并行读取导致matchesData未加载完成的问题 - 排序处理:用
Object.entries()将投手对象转为数组,排序时把economy转为浮点数,避免字符串排序的数值顺序错误 - 格式转换:通过
map()将排序后的投手数据转为{投手名: 统计数据}的单个对象,组成目标数组格式 - 边界处理:计算经济值时判断投球数是否为0,避免出现除以0的错误
内容的提问来源于stack exchange,提问作者user27811117
相关产品推荐
相关产品推荐

