You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对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))
      })
  });

关键逻辑说明

  1. 数据依赖修复:将deliveries.csv的读取嵌套在matches.csv的end事件内,避免因并行读取导致matchesData未加载完成的问题
  2. 排序处理:用Object.entries()将投手对象转为数组,排序时把economy转为浮点数,避免字符串排序的数值顺序错误
  3. 格式转换:通过map()将排序后的投手数据转为{投手名: 统计数据}的单个对象,组成目标数组格式
  4. 边界处理:计算经济值时判断投球数是否为0,避免出现除以0的错误

内容的提问来源于stack exchange,提问作者user27811117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:08:15