从嵌套对象提取数据:FlatMap与Reduce的效率及可读性对比
提取嵌套数组中的
completionDate值:对比flatMap与reduce的实现与效率 需求背景
现有一个包含多个元素的testResults数组,每个元素的response子数组可能包含1个或多个对象,需要将所有对象中的completionDate值提取到单独数组中。
数据集示例
const testResults = [ { "value": { "data": { "response": [ { "completionDate": "2024-10-10T17:44:00", }, { "completionDate": "2024-10-11T17:44:00", } ] } } }, // 更多元素... ];
两种实现方案
flatMap实现
const timestamps = testResults.flatMap(result => result.value.data.response.map(check => check?.completionDate) );
reduce实现
const timestamps = testResults.reduce((acc, res) => { res.value.data.response.forEach(check => { acc.push(check.completionDate); }); return acc; }, []);
测试结果
通过console.time单次测试得到:
flatMap: 0.103ms
reduce: 0.067ms
疑问:这个结果真的能说明reduce效率高出很多吗?
解答
可读性对比
flatMap是声明式写法,逻辑直观:先对每个testResults元素映射出response中的completionDate数组,再自动扁平化。熟悉数组方法的团队成员一眼就能理解代码意图,维护成本更低。reduce是命令式写法,需要阅读内部的forEach和push逻辑才能明白是在收集值,可读性稍弱,但逻辑本身不复杂。
效率测试的局限性
单次console.time的结果参考价值有限,JS引擎的即时编译(JIT)、垃圾回收、当前线程负载等因素都会影响单次执行的耗时。要得到准确的对比结果,应该进行多次循环测试(比如重复执行10000次取平均值)。
而且在绝大多数业务场景下,这两种方法的性能差异可以忽略不计——只有当你处理十万级甚至百万级的超大数组时,这种微小的差异才可能体现出来。其他实现方法
也可以用双层for...of循环,写法同样直观,性能和reduce接近:const timestamps = []; for (const res of testResults) { for (const check of res.value.data.response) { timestamps.push(check.completionDate); } }
总结
- 优先推荐
flatMap:代码简洁、意图清晰,团队协作时的可读性和维护性更好。 - 如果处理超大规模数据,或者团队对
reduce/命令式写法更熟悉,再考虑reduce或for...of循环。
内容的提问来源于stack exchange,提问作者physicsboy
相关产品推荐
相关产品推荐

