TypeScript中匹配3个数组取值的高效遍历方法,解决Excel导出过慢问题
性能优化方案
核心问题分析
原代码采用三重循环嵌套,时间复杂度为O(数组1长度 × 数组2长度 × 数组3长度),当三个数组数据量较大时,遍历成本会指数级上升,这是导出耗时过长的核心原因。
优化思路
通过哈希表(HashMap)提前索引第三个数组的匹配条件,将内层匹配的时间复杂度从O(n)降到O(1),整体时间复杂度降到O(数组3长度 + 数组1长度 × 数组2长度),性能可以提升数十到数百倍。
具体实现代码
首先定义类型接口规范结构:
// 定义各数组元素的类型 interface Array1Item { item_1: string; item_2: string; // 其他字段按需补充 } interface Array2Item { item_1: string; // 其他字段按需补充 } interface Array3Item { item_1: string; item_2: string; item_3: null | '' | 'sells' | 'buys'; // 其他字段按需补充 }
然后预处理哈希表,再执行业务逻辑:
// 1. 提前预处理第三个数组,生成哈希索引 const grapeMap = new Map<string, Array3Item['item_3']>(); // 如果需要用到Array3的其他字段,可把Map的value类型改为Array3Item,存储整个元素 for (const grapeItem of this.arrayNumberThree[0] as Array3Item[]) { // 用不会出现在业务值中的分隔符拼接两个匹配字段作为key const key = `${grapeItem.item_1}||${grapeItem.item_2}`; grapeMap.set(key, grapeItem.item_3); } // 2. 遍历前两个数组,直接查哈希表匹配 for (const orangeItem of this.arrayNumberOne[0] as Array1Item[]) { const orangeThree = orangeItem.item_1.concat(orangeItem.item_2); for (const appleItem of this.arrayNumberTwo[0] as Array2Item[]) { const appleOne = appleItem.item_1; const matchKey = `${orangeThree}||${appleOne}`; const grapeThree = grapeMap.get(matchKey); // 没有匹配到直接跳过,无需额外判断 if (grapeThree === undefined) continue; // 原有业务逻辑不变 if (grapeThree == null || grapeThree == '') { // print to response to excel } else if (grapeThree == 'sells') { // print stuff to excel } else if (grapeThree == 'buys') { // print stuff to excel } } }
额外优化建议
- 如果
arrayNumberTwo中有重复的item_1值,可以提前对arrayNumberTwo去重,减少第二层循环的遍历次数 - 如果Excel生成逻辑存在重复IO操作,可以先把所有行数据缓存到数组中,最后一次性写入Excel,减少IO开销
- 如果业务中
item_1或item_2可能包含||字符,可以替换为其他不会出现的分隔符(比如\u0000空字符)避免哈希key冲突 - 可以提前计算所有
orangeThree的值,避免每次拼接的重复开销
内容的提问来源于stack exchange,提问作者MK212test
相关产品推荐
相关产品推荐

