如何编写通用函数按序提取动态嵌套数组中的所有id?
从动态嵌套数组中按序提取所有id的通用方法
我有一个动态嵌套数组,其嵌套层级不固定,有时是2层,有时是3层,最多可达10层。需要按顺序查询其中的所有id并将它们放入一个数组中。以下是两个示例:
示例一
let data = [ { "field": "age", "items": [ { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 12 } ] }, { "field":"gender", "items": [ { "id": 10 }, { "id": 32 } ] } ] }, { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 29 } ] } ] } ] }, { "field": "age", "items": [ { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 31 } ] }, { "field":"gender", "items": [ { "id": 15 }, { "id": 39 } ] } ] }, { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 55 } ] } ] } ] }, { "field": "age", "items": [ { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 43 } ] }, ] }, { "field": "name", "items": [ { "field":"gender", "items": [ { "id": 41 } ] }, { "field":"gender", "items": [ { "id": 6 }, { "id": 98 } ] } ] } ] } ]
结果: [12,10,32,29,31,15,39,55,43,41,6,98]
示例二
[ { "field": "age", "items": [ { "field": "name", items: [ { "field":"gender", "items": [ { "field": "height", "items": [ { "id": 12 } ] } ] }, { "field":"gender", "items": [ { "field": "height", "items": [ { "id": 14 } ] }, { "field": "height", "items": [ { "id": 19 } ] } ] } ] }, { "field": "name", items: [ { "field":"gender", "items": [ { "field": "height", "items": [ { "id": 22 } ] } ] } ] } ] }, { "field": "age", "items": [ { "field": "name", items: [ { "field":"gender", "items": [ { "field": "height", "items": [ { "id": 24 } ] } ] }, { "field":"gender", "items": [ { "field": "height", "items": [ { "id": 25 } ] }, { "field": "height", "items": [ { "id": 27 }, { "id": 29 }, { "id": 21 } ] }, { "field": "height", "items": [ { "id": 88 } ] } ] } ] }, ] } ]
结果: [12,14,19,22,24,25,27,29,21,88]
尝试的代码(未得到正确结果)
let level = getLevel(data); let result = []; data.forEach(res => { let flatData = res.items.flat(level); flatData.forEach(ele => { result.push(ele.id); }) })
解决方案
你的问题在于flat(level)需要明确知道嵌套层级,但实际数据的层级可能不一致,且getLevel函数未必能准确计算到最底层的深度。最可靠的方法是用递归遍历,不管嵌套多少层,只要遇到有items的节点就继续深入,遇到有id的节点就提取。
通用递归函数
function extractIds(arr) { let ids = []; for (const item of arr) { // 如果当前节点有id,加入结果数组 if (item.id !== undefined) { ids.push(item.id); } // 如果当前节点有items,递归处理子数组 if (item.items && Array.isArray(item.items)) { ids = ids.concat(extractIds(item.items)); } } return ids; } // 使用示例 const result = extractIds(data); console.log(result);
解释
- 函数接收一个数组作为参数,初始化空数组存储id
- 遍历数组中的每个元素:
- 如果元素包含
id属性,将其值加入结果数组 - 如果元素包含
items且是数组,递归调用自身处理子数组,并将返回的id数组合并到结果中
- 如果元素包含
- 这种方法不依赖固定层级,无论嵌套深度是多少(2层到10层),都能按顺序提取所有id,完全符合需求。
另一种简洁写法(使用reduce)
如果喜欢更紧凑的风格,可以用Array.reduce实现:
const extractIds = arr => arr.reduce((acc, item) => { if (item.id !== undefined) acc.push(item.id); if (item.items && Array.isArray(item.items)) acc.push(...extractIds(item.items)); return acc; }, []);
内容的提问来源于stack exchange,提问作者user19222827
相关产品推荐
相关产品推荐

