如何用F# CsvProvider将CSV多列数据转为int数组存入自定义类型?
解决CsvProvider读取多列并转为int数组的问题
嗨,作为F#新手碰到这种超多列的CSV处理需求确实容易懵,我来给你两种实用的解决方案,帮你把数据转成想要的DigitRecord类型!
首先先确认你的CsvProvider类型定义应该是类似这样的(记得替换成你的实际CSV文件路径):
type CSV = CsvProvider<"your_data_file.csv"> type DigitRecord = { Title:string; Digits:int[] }
方案一:通用适配(不管列名是什么)
这种方法不需要依赖列名的规律,自动过滤掉Title列,提取剩下的所有列数据转成int数组,灵活性拉满:
let dataRecords = CSV.Rows |> Seq.map (fun record -> // 获取所有列的名称 let allColumnNames = CSV.Columns |> Array.map (fun col -> col.Name) // 过滤掉Title列,剩下的就是数字列 let digitColumns = allColumnNames |> Array.filter (fun name -> name <> "Title") // 遍历数字列,动态获取每一列的整数值 let digitsArray = digitColumns |> Array.map (fun colName -> record.GetColumn<int>(colName)) // 组装成目标类型 { Title = record.Title; Digits = digitsArray } )
方案二:针对列名规律的场景(D1到D700)
如果你的数字列名是固定的D1、D2...D700,那可以直接生成列名字符串数组,代码更简洁:
// 提前生成所有数字列的名称 let digitColumnNames = [| for i in 1..700 -> sprintf "D%d" i |] let dataRecords = CSV.Rows |> Seq.map (fun record -> let digitsArray = digitColumnNames |> Array.map (fun colName -> record.GetColumn<int>(colName)) { Title = record.Title; Digits = digitsArray } )
小提示
GetColumn<int>会自动帮你把CSV里的字符串转成整数,如果某列存在非整数数据,会抛出异常。如果需要处理这种情况,可以改成GetColumn<Option<int>>,然后再处理None值。- 确保你的CSV文件第一行是正确的表头(就是你示例里的
Title D1 D2 ... D700),CsvProvider会自动识别表头作为属性名。
内容的提问来源于stack exchange,提问作者Ayto Maximo
相关产品推荐
相关产品推荐

