Node.js实现多值匹配:从源列表筛选目标项关联值
问题解决:为指定列表项匹配关联多值
问题背景
现有两个字符串列表:
const lista_source = 'B10L-A2,AABan38711$B10L-A2,AABan38811$B12A-A,AABan38912$B14-A2,AABan39314$B16B-A,AABan39616$B12A-A,AABan39818$B16L-B,AABan39919$B16L-B,AABan40019$B12A-A,AABan41112' const second_list = 'B10L-A2,B12A-A,B16L-B'
期望得到的结果格式:
result = [B10L-A2:AABan38711,AABan38811],[B12A-A:AABan38912,AABan41112,AABan39818],[B16L-B:AABan39919,AABan40019]
简言之,需要为second_list中的每个项,匹配lista_source里所有对应的关联值,同时将结果写入CSV文件。原尝试代码未能成功:
const first_list_object= first_list.split('$'); const second_list_object= second_list.split(','); for (let i = 0; i < second_list_object.length; i++) { let results= first_list_object.filter(x => x.includes(second_list_object[i])); console.log(results); writer = csvWriter({ sendHeaders: false }); writer.pipe(fs.createWriteStream(__dirname + '/lista.csv', { flags: 'a' })); writer.write({ results }); }
原代码问题分析
- 重复创建写入流:每次循环都新建
csvWriter并重新绑定文件流,会导致文件写入异常且效率低下。 - 数据未正确处理:
filter返回的是包含键值对的字符串数组,没有拆分出键和关联值,也未整理成期望的格式。 - CSV写入格式错误:
writer.write传入的对象结构不符合CSV要求,无法生成规范的表格内容。
解决方案
方案一:修正原逻辑,正确处理数据并写入CSV
const fs = require('fs'); const csvWriter = require('csv-writer').createObjectCsvWriter; const lista_source = 'B10L-A2,AABan38711$B10L-A2,AABan38811$B12A-A,AABan38912$B14-A2,AABan39314$B16B-A,AABan39616$B12A-A,AABan39818$B16L-B,AABan39919$B16L-B,AABan40019$B12A-A,AABan41112'; const second_list = 'B10L-A2,B12A-A,B16L-B'; // 拆分源数据为键值对数组 const sourcePairs = lista_source.split('$').map(item => { const [key, value] = item.split(','); return { key, value }; }); const targetKeys = second_list.split(','); // 初始化CSV写入器,指定列名 const writer = csvWriter({ path: __dirname + '/lista.csv', header: [ { id: 'key', title: 'KEY' }, { id: 'values', title: 'ASSOCIATED_VALUES' } ] }); // 处理每个目标键,收集关联值 const records = targetKeys.map(key => { const values = sourcePairs .filter(pair => pair.key === key) .map(pair => pair.value) .join(','); // 生成你期望的格式字符串 const formattedStr = `[${key}:${values}]`; console.log(formattedStr); return { key, values }; }); // 一次性写入所有记录 writer.writeRecords(records) .then(() => console.log('CSV文件写入完成')) .catch(err => console.error('写入失败:', err));
方案二:使用Map预处理,提升效率(更优方案)
如果源数据量较大,多次调用filter的时间复杂度为O(n*m)(n是源数据长度,m是目标键数量),用Map预处理可将时间复杂度降至O(n+m),查询效率更高:
const fs = require('fs'); const csvWriter = require('csv-writer').createObjectCsvWriter; const lista_source = 'B10L-A2,AABan38711$B10L-A2,AABan38811$B12A-A,AABan38912$B14-A2,AABan39314$B16B-A,AABan39616$B12A-A,AABan39818$B16L-B,AABan39919$B16L-B,AABan40019$B12A-A,AABan41112'; const second_list = 'B10L-A2,B12A-A,B16L-B'; // 预处理源数据为Map,键对应值数组 const valueMap = new Map(); lista_source.split('$').forEach(item => { const [key, value] = item.split(','); if (!valueMap.has(key)) { valueMap.set(key, []); } valueMap.get(key).push(value); }); const targetKeys = second_list.split(','); const writer = csvWriter({ path: __dirname + '/lista.csv', header: [ { id: 'key', title: 'KEY' }, { id: 'values', title: 'ASSOCIATED_VALUES' } ] }); const records = targetKeys.map(key => { const values = valueMap.get(key)?.join(',') || ''; const formattedStr = `[${key}:${values}]`; console.log(formattedStr); return { key, values }; }); writer.writeRecords(records) .then(() => console.log('CSV写入完成')) .catch(err => console.error('错误:', err));
说明
- 两种方案都会生成你期望的格式字符串(可通过
console.log查看),同时将结果按规范写入CSV文件,每行包含键和对应的关联值列表。 - Map预处理方案更适合大数据量场景,查询效率更高。
内容的提问来源于stack exchange,提问作者Denes
相关产品推荐
相关产品推荐

