JavaScript中如何在单个方法内合并实现map与filter操作
优化方案
你完全可以用flatMap把匹配、过滤、取值三步逻辑合并成单次数组遍历,代码内聚性更强,可读性更好,完全符合你要的「可读性层面高效」的要求。
推荐写法(语义最直观)
flatMap的特性是会把每个元素返回的数组自动拍平一层:匹配失败时返回空数组,就相当于过滤掉该元素;匹配成功时返回只存目标文件名的单元素数组,就相当于保留该值,一步完成原来三次链式调用的逻辑:
const filteredFiles = files.flatMap(filePath => { const matchResult = filePath.match(/.*\/(.*)\.xml$/) return matchResult ? [matchResult[1]] : [] })
注:给正则补了结尾锚定符
$,修复原正则会错误匹配xxx.xml.bak这类非xml后缀文件的问题,逻辑更严谨。
其他可选写法对比
用
reduce实现:const filteredFiles = files.reduce((result, filePath) => { const matchResult = filePath.match(/.*\/(.*)\.xml$/) if (matchResult) result.push(matchResult[1]) return result }, [])这个写法性能和flatMap差不多,但需要手动维护结果数组的入栈操作,语义上不如flatMap贴合「单元素映射为0或1个目标值」的场景,可读性稍差。
不推荐的写法:
不要用外部临时变量在filter和map之间传值,类似下面的写法会引入隐式状态依赖,读代码时需要额外追踪临时变量的赋值逻辑,反而降低可读性:// 反面示例,请勿使用 let tempMatch const filteredFiles = files .filter(f => (tempMatch = f.match(/.*\/(.*)\.xml$/))) .map(() => tempMatch[1])
内容的提问来源于stack exchange,提问作者Koen
相关产品推荐
相关产品推荐

