提取TypeScript对象对比函数return内逻辑优化代码可读性
问题分析与重构方案
原实现存在的问题
- 类型完全用
any,丢失TS类型校验与提示能力 - 变量命名冲突:filter循环内部变量和上层入参重名为
secArr,极易造成逻辑误解 - 冗余异步包装:整个对比逻辑为同步操作,不需要
async/await与Promise包装 - 嵌套层级过深:判断逻辑全部嵌套在return语句中,可读性差
- 性能不佳:每次判断都要全量遍历第二个数组,时间复杂度为O(n*m),数据量大时性能差
重构后易读版本
基础可读实现(逻辑完全抽离,每步语义明确)
首先定义数组元素类型替代any:
interface FileItem { codCountry: string; fileName: string; }
重构后的对比函数:
/** * 提取仅在第一个数组中存在的元素,匹配依据为fileName字段 * @param firstArr 待提取元素的目标数组 * @param secondArr 对比参照数组 * @returns 仅存在于firstArr中的元素集合 */ public getItemsOnlyInFirstArr(firstArr: FileItem[], secondArr: FileItem[]): FileItem[] { // 第一步:提取第二个数组所有fileName存入集合 const secondFileNames = secondArr.map(item => item.fileName); // 第二步:筛选第一个数组中fileName不在上述集合中的元素 const result = firstArr.filter(currentItem => { return !secondFileNames.includes(currentItem.fileName); }); return result; }
调用方式(完全不需要多余的await):
const onlyObj1 = this.getItemsOnlyInFirstArr(obj1, obj2);
运行后得到的结果符合预期:[{ codCountry: 'CO', fileName: 'CO_TES.txt' }]
高性能优化版(适合数据量较大的场景)
用Set存储fileName,存在性判断时间复杂度降为O(1),整体时间复杂度优化到O(n+m):
public getItemsOnlyInFirstArr(firstArr: FileItem[], secondArr: FileItem[]): FileItem[] { const secondFileNameSet = new Set(secondArr.map(item => item.fileName)); return firstArr.filter(item => !secondFileNameSet.has(item.fileName)); }
原代码逻辑拆解
原代码虽然写法不合理,但实际逻辑和需求是匹配的,拆解如下:
- 调用
await this.objectComparer(obj2, obj1)时,函数返回的是一个过滤用的判断函数,而非直接返回结果 - 返回的判断函数接收
current参数,对应obj1.filter遍历的每一个元素 - 内部遍历第一个入参
obj2,查找是否存在fileName和current的fileName相等的元素,没有则保留该元素 - 原代码最大的误导点是filter内部的循环变量命名为
secArr,和函数第二个入参重名,实际上该变量是obj2的单条遍历元素
内容的提问来源于stack exchange,提问作者main
相关产品推荐
相关产品推荐

