如何使用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),步骤如下:
- 先遍历其中一个文件的所有行,以
city为键存储到Map中,保存该行的所有数据。 - 再遍历另一个文件的行,通过
city键在Map中查找:- 找到则合并两行数据;
- 没找到则将该行数据存入Map。
- 最后将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
相关产品推荐
相关产品推荐

