如何使用Lodash更优雅地统计嵌套对象中rooms数组的总长度?
优雅统计嵌套对象中rooms数组的总长度
问题背景
有如下嵌套结构的对象,需要统计所有rooms数组的总长度:
{ inspectionReport: { property: { structures: [ { finishedSpaces: [ { levels: [ { rooms: [ // 待统计的元素 ] } ] } ] } ] } } }
当前使用多层forEach累加的方式实现,但写法不够简洁优雅,希望找到更优方案。现有代码如下:
let roomCount = 0; results['inspectionReport']['property']['structures'].forEach(structure => { structure['finishedSpaces'].forEach(finishedSpace => { finishedSpace['levels'].forEach(level => { roomCount += level['rooms'].length; }); }); });
优化方案
方案1:链式使用Array.reduce
通过嵌套reduce替代forEach,避免外部变量,实现纯函数式累加:
const roomCount = results.inspectionReport.property.structures.reduce((total, structure) => { return total + structure.finishedSpaces.reduce((sum, space) => { return sum + space.levels.reduce((count, level) => { return count + level.rooms.length; }, 0); }, 0); }, 0);
方案2:flatMap + reduce(ES2019+)
利用flatMap逐层展开嵌套数组,最后统一统计,代码更简洁直观:
const roomCount = results.inspectionReport.property.structures .flatMap(structure => structure.finishedSpaces) .flatMap(space => space.levels) .reduce((total, level) => total + level.rooms.length, 0);
方案3:递归遍历(应对动态嵌套结构)
如果对象的嵌套层级不确定或可能变化,递归函数可以灵活适配任意嵌套深度:
function countRooms(target) { let count = 0; for (const key in target) { if (Array.isArray(target[key])) { target[key].forEach(item => count += countRooms(item)); } else if (key === 'rooms' && Array.isArray(target[key])) { count += target[key].length; } else if (typeof target[key] === 'object' && target[key] !== null) { count += countRooms(target[key]); } } return count; } const roomCount = countRooms(results.inspectionReport.property);
额外优化:可选链处理空值
如果存在属性可能不存在的情况,使用可选链?.避免报错,同时默认返回0:
const roomCount = results?.inspectionReport?.property?.structures ?.flatMap(s => s?.finishedSpaces) ?.flatMap(fs => fs?.levels) ?.reduce((total, level) => total + (level?.rooms?.length || 0), 0) || 0;
内容的提问来源于stack exchange,提问作者Justin Morgan
相关产品推荐
相关产品推荐

