如何简化JavaScript嵌套Map?无需嵌套访问modal数组的方法
问题描述
现有如下JavaScript嵌套Map代码:
blocks.map((item) => { return item.SubCategory.map((subItem) => { return subItem.modal.map((modal) => { let Blocks = selectedBlock === item.Category; let SubBlocks = selectedSubBlock === subItem.id; if (SubBlocks && Blocks) { return bm.add(modal.id, { label: modal.label, content: modal.content, }); } return null; }); }); });
请问是否存在类似Lodash的get方法(如get(val, 'val.val.val'))的数组操作方式,无需嵌套即可访问modal数组?
解决方案
当然有,你可以通过数组深度扁平化的方式避开嵌套循环,直接获取所有层级的modal项,下面是几种实用的实现方式:
1. 原生JS结合递归实现深度扁平化
原生flatMap只能处理一层嵌套,配合递归可以实现深度遍历:
// 深度扁平化函数 function flattenDeep(arr) { return arr.flatMap(item => Array.isArray(item) ? flattenDeep(item) : item ); } // 提取所有modal并保留上下文 const allModals = flattenDeep(blocks.map(item => item.SubCategory.map(subItem => subItem.modal.map(modal => ({ modal, item, subItem })) ) )); // 筛选并处理符合条件的modal allModals.forEach(({ modal, item, subItem }) => { const isBlockMatch = selectedBlock === item.Category; const isSubBlockMatch = selectedSubBlock === subItem.id; if (isBlockMatch && isSubBlockMatch) { bm.add(modal.id, { label: modal.label, content: modal.content, }); } });
2. 使用Lodash的flatMapDeep
Lodash直接提供了深度扁平化的工具方法,能一步处理多层嵌套:
// 提取所有modal及上下文 const allModals = _.flatMapDeep(blocks, item => _.flatMapDeep(item.SubCategory, subItem => subItem.modal.map(modal => ({ modal, item, subItem })) ) ); // 后续筛选处理逻辑和上面一致 allModals.forEach(({ modal, item, subItem }) => { const isBlockMatch = selectedBlock === item.Category; const isSubBlockMatch = selectedSubBlock === subItem.id; if (isBlockMatch && isSubBlockMatch) { bm.add(modal.id, { label: modal.label, content: modal.content, }); } });
3. 生成器函数遍历所有modal
如果不想依赖工具库,也可以用生成器函数实现深度遍历:
// 生成器:遍历所有层级的modal并返回上下文 function* traverseAllModals(blocks) { for (const item of blocks) { for (const subItem of item.SubCategory) { for (const modal of subItem.modal) { yield { modal, item, subItem }; } } } } // 遍历处理 for (const { modal, item, subItem } of traverseAllModals(blocks)) { const isBlockMatch = selectedBlock === item.Category; const isSubBlockMatch = selectedSubBlock === subItem.id; if (isBlockMatch && isSubBlockMatch) { bm.add(modal.id, { label: modal.label, content: modal.content, }); } }
这些方法都能避免嵌套的map调用,直接获取所有需要处理的modal项,同时保留了判断所需的item和subItem上下文。
内容的提问来源于stack exchange,提问作者Rakul Agn
相关产品推荐
相关产品推荐

