跳转到主要内容
模块 8 · 第 2 课(共 4)课程中的30/32~15 min
模块课程(2/4)

挑战:CSV 解析器

CSV 格式(逗号分隔值)无处不在:从 Excel 导出、数据库转储、 命令行工具的输出。解析它是一个小挑战,结合了 split、map、 解构和对象构造。

格式

最小的 CSV 是一个多行字符串:第一行是 标题(列名称),然后是一个 每条记录行,字段以逗号分隔。

Code
nome,eta,citta
Alice,30,Roma
Bob,25,Milano

经典的目标是将其转换为对象数组:

JS
[
  { nome: 'Alice', eta: '30', citta: 'Roma' },
  { nome: 'Bob', eta: '25', citta: 'Milano' },
];

3步食谱

  1. 按行分割字符串:csv.split('\n')
  2. 提取标题行:第一行,以逗号分隔
  3. 映射 每个剩余行到一个对象,将每个字段与匹配的标头配对
JS
function parseCSV(csv) {
  const righe = csv.split('\n');
  const intestazione = righe[0].split(',');
  return righe.slice(1).map((riga) => {
    const campi = riga.split(',');
    const record = {};
    intestazione.forEach((nome, i) => {
      record[nome] = campi[i];
    });
    return record;
  });
}

更现代的替代方案:

JS
const record = Object.fromEntries(intestazione.map((nome, i) => [nome, campi[i]]));

转换类型

解析的字段始终是字符串。如果您知道某些列是数字:

JS
record.eta = Number(record.eta);

或者写一个小“模式”:

JS
const numeriche = new Set(['eta', 'prezzo']);
intestazione.forEach((nome, i) => {
  const v = campi[i];
  record[nome] = numeriche.has(nome) ? Number(v) : v;
});

尝试一下

锻炼#js.m8.l2.e1
尝试:0加载中...

定义采用 CSV 字符串的“parseCSV(csv)”(第一行 = 标题,逗号作为分隔符)。返回带有标题键的对象数组。所有值都保留为字符串。忽略空行。

正在加载编辑器...
显示提示

在换行符处拆分,第一行 = 标题,映射其余行,Object.fromEntries。

3 次尝试后可用的解决方案

复习练习

锻炼#js.m8.l2.e2
尝试:0加载中...

定义“columnMean(csv, columnName)”,用于解析 CSV、将列值转换为数字并返回其平均值(数字)。如果没有数据行则返回 0。

正在加载编辑器...
显示提示

找到列索引,映射行→数字,减少总和,除以长度。

3 次尝试后可用的解决方案