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

如何使用JavaScript/NodeJS匹配并合并两个CSV文件的数据?

基于城市合并两个CSV文件并优化实现

需求说明

我有两个独立的CSV文件:

population.csv

city        | State         | Population
-----------------------------------------
Seattle     | Washington    | 63269
Birmingham  | Alabama       | 212113

temperature.csv

index | city         | JAN | FEB | ANN
-----------------------------------------
0     | Birmingham   | 46  | 53  | 
3     | Juneau       | 19  | 25  | 38

需要基于城市是否相同合并数据,形成如下格式(无重叠项留空):

index | city         | JAN | FEB | ANN | State      | Population
-------------------------------------------------------------------------
0     | Birmingham   | 46  | 53  |     | Alabama    | 212113
3     | Juneau       | 19  | 25  | 38  |            |
      | Seattle      |     |     |     | Washington | 63269

现有实现

目前我写出了时间复杂度为O(n²)的代码:

const popRows = await parse(fs.readFileSync('./data/population.csv', 'utf8'), {
    columns: true,
    delimiter: ',',
});

const tempRows = await parse(fs.readFileSync('./data/temperature.csv', 'utf8'), {
    columns: true,
    delimiter: ',',
});

const combinedRows = [];

popRows.forEach(popRow => {
   tempRows.forEach(tempRow => if (popRow.city === tempRow.city) combinedRows.push({...popRow, ...tempRow}))
});

请问我的思路是否正确?有没有更优的实现方式?


回答

现有思路的问题

你的现有思路不完全正确:

  • 只处理了两个文件中同时存在的城市(比如Birmingham),遗漏了仅在population.csv中的城市(Seattle)和仅在temperature.csv中的城市(Juneau),无法得到你想要的完整结果。
  • 嵌套循环的时间复杂度是O(n*m)(n是population行数,m是temperature行数),数据量较大时性能会明显下降。

优化实现方案

可以通过**哈希表(Map)**将时间复杂度降低到O(n+m),步骤如下:

  1. 先遍历其中一个文件的所有行,以city为键存储到Map中,保存该行的所有数据。
  2. 再遍历另一个文件的行,通过city键在Map中查找:
    • 找到则合并两行数据;
    • 没找到则将该行数据存入Map。
  3. 最后将Map中的值提取为数组,就是完整的合并结果。

示例代码:

const popRows = await parse(fs.readFileSync('./data/population.csv', 'utf8'), {
    columns: true,
    delimiter: ',',
});

const tempRows = await parse(fs.readFileSync('./data/temperature.csv', 'utf8'), {
    columns: true,
    delimiter: ',',
});

// 用Map存储以city为键的所有数据
const cityMap = new Map();

// 先存入temperature的数据,保证顺序和示例一致
tempRows.forEach(row => {
    cityMap.set(row.city, { ...row });
});

// 处理population的数据,合并或新增
popRows.forEach(row => {
    const city = row.city;
    if (cityMap.has(city)) {
        // 合并已有数据
        cityMap.set(city, { ...cityMap.get(city), ...row });
    } else {
        // 新增仅存在于population的城市
        cityMap.set(city, { ...row });
    }
});

// 将Map的值转为数组,得到最终合并结果
const combinedRows = Array.from(cityMap.values());

补充说明

  • 如果需要调整结果的城市顺序,只需调换两个文件的遍历顺序即可。
  • 对于空值的显示,CSV解析库通常会保留空字符串或undefined,最终输出时可根据需求格式化为空白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:08:30