如何用原生JavaScript将多行数据的CSV转换为嵌套JSON
问题:CSV转合并式JavaScript对象/JSON需求及代码修复
需求说明
- 将给定CSV转换为合并后的单一JavaScript对象/JSON,而非每行生成独立对象
- 需把
HeightOptions/Options字段的点分隔字符串转为数字数组
原始CSV数据
Name,Time,HeightOptions/WidthRange,HeightOptions/Options EGBL,Today,12,12.13.14.15.16 ,,26,12.13.14.15.16
期望输出
{ Name: "EGBL", Time: "Today", HeightOptions: [ { WidthRange: "12", Options: [12,13,14,15,16] }, { WidthRange: "26", Options: [12,13,14,15,16] } ] }
当前代码及问题
现有代码会将每行转为独立对象,且未处理Options的数组转换:
const CSV = (csv) => { var attrs = csv.splice(0, 1); console.log("attrsattrs", attrs); var result = csv.map(function (row) { var obj = {}; var rowData = row.split(","); attrs[0].split(",").forEach(function (val, idx) { obj = constructObj(val, obj, rowData[idx]); }); return obj; }); function constructObj(str, parentObj, data) { if (str.split("/").length === 1) { parentObj[str] = data; return parentObj; } var curKey = str.split("/")[0]; if (!parentObj[curKey]) parentObj[curKey] = {}; parentObj[curKey] = constructObj( str.split("/").slice(1).join("/"), parentObj[curKey], data ); return parentObj; } console.log("resultresultresult", result); };
核心问题
- 每行生成独立对象,未合并共享
Name/Time的行数据 HeightOptions/Options的点分隔字符串未转为数字数组HeightOptions被处理为对象而非数组
修复后的代码
const convertCSVToObj = (csv) => { // 过滤空行,分离表头与数据行 const [headerRow, ...rows] = csv.filter(row => row.trim() !== ''); const headers = headerRow.split(',').map(h => h.trim()); const result = {}; // 初始化基础字段和HeightOptions数组 let baseName = ''; let baseTime = ''; result.HeightOptions = []; rows.forEach(row => { const rowData = row.split(',').map(d => d.trim()); const heightOpt = {}; headers.forEach((header, idx) => { const value = rowData[idx]; if (!value) return; // 提取第一行的Name/Time作为基础字段 if (header === 'Name') { baseName = value; return; } if (header === 'Time') { baseTime = value; return; } // 处理HeightOptions下的子字段 const [parentKey, childKey] = header.split('/'); if (parentKey === 'HeightOptions') { if (childKey === 'Options') { // 将点分隔字符串转为数字数组 heightOpt[childKey] = value.split('.').map(Number); } else { heightOpt[childKey] = value; } } }); // 将当前行的HeightOption数据推入数组 if (Object.keys(heightOpt).length > 0) { result.HeightOptions.push(heightOpt); } }); // 填充基础字段 result.Name = baseName; result.Time = baseTime; console.log(result); return result; }; // 测试调用示例 const csvData = [ 'Name,Time,HeightOptions/WidthRange,HeightOptions/Options', 'EGBL,Today,12,12.13.14.15.16', ',,26,12.13.14.15.16' ]; convertCSVToObj(csvData);
修复要点
- 合并行数据:提取第一行的
Name/Time作为全局字段,后续行的HeightOptions统一存入数组 - Options类型转换:通过
split('.')分割字符串后,用map(Number)转为数字数组 - 结构调整:将
HeightOptions初始化为数组,每行对应数据作为对象推入数组
内容的提问来源于stack exchange,提问作者Keshav Kewlani
相关产品推荐
相关产品推荐

