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

如何在Go中将1:N结构的CSV文件归一化为Map?

最优实现方案(Go语言)

你当前的代码存在几个核心问题:

  • 每次循环都新建map,无法累积同一name对应的多个note
  • 未跳过表头,会把第一行的name和note也混入结果
  • 用excelize处理CSV属于冗余操作,Go标准库的encoding/csv更适配CSV场景
  • 未统一name的大小写(你需要的是小写的joe、ashley)

以下是针对CSV文件的最优实现:

1. 核心思路

  • 用Go标准库encoding/csv读取文件,无需额外依赖
  • 初始化全局map存储结果,避免循环内重复创建
  • 跳过表头行,只处理数据行
  • 清洗name字段(去除单引号、转小写),将note追加到对应key的切片中

完整CSV处理代码

package main

import (
    "encoding/csv"
    "fmt"
    "os"
    "strings"
)

func main() {
    // 打开目标CSV文件
    file, err := os.Open("data.csv")
    if err != nil {
        fmt.Printf("打开文件失败: %v\n", err)
        return
    }
    defer file.Close()

    // 初始化CSV读取器,开启宽松引号模式适配带单引号的字段
    reader := csv.NewReader(file)
    reader.LazyQuotes = true

    // 读取所有行数据
    rows, err := reader.ReadAll()
    if err != nil {
        fmt.Printf("读取CSV失败: %v\n", err)
        return
    }

    // 初始化结果map
    result := make(map[string][]string)

    // 跳过表头,遍历数据行
    for _, row := range rows[1:] {
        if len(row) < 2 {
            continue // 跳过格式不完整的行
        }
        // 清洗name字段:去除单引号并转小写
        name := strings.Trim(row[0], "'")
        name = strings.ToLower(name)
        // 清洗note字段:去除多余空格
        note := strings.TrimSpace(row[1])
        // 将note追加到对应name的切片中
        result[name] = append(result[name], note)
    }

    // 输出最终结果
    fmt.Printf("%v\n", result)
}

若需处理Excel(xlsx)文件

如果你的数据源是xlsx而非CSV,修改后的代码如下:

package main

import (
    "fmt"
    "strings"

    "github.com/xuri/excelize/v2"
)

func main() {
    fileName := "new.xlsx"
    xlsx, err := excelize.OpenFile(fileName)
    if err != nil {
        fmt.Printf("打开Excel失败: %v\n", err)
        return
    }
    defer xlsx.Close()

    rows, err := xlsx.Rows("Sheet1")
    if err != nil {
        fmt.Printf("读取Sheet失败: %v\n", err)
        return
    }

    result := make(map[string][]string)
    isHeader := true // 标记是否为表头行

    for rows.Next() {
        columns, err := rows.Columns()
        if err != nil {
            fmt.Printf("读取行失败: %v\n", err)
            continue
        }
        if isHeader {
            isHeader = false
            continue // 跳过表头
        }
        if len(columns) < 2 {
            continue
        }
        name := strings.Trim(columns[0], "'")
        name = strings.ToLower(name)
        note := strings.TrimSpace(columns[1])
        result[name] = append(result[name], note)
    }

    fmt.Printf("%v\n", result)
}

方案优势

  • 处理CSV时依赖标准库,性能稳定、无额外依赖
  • 逻辑简洁,仅做必要的字符串清洗,效率高
  • 自动处理key不存在的情况,无需手动判断
  • 包含错误处理和边界兼容(如格式错误的行)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:46:18