在处理复杂业务数据时,嵌套对象数组是非常常见的数据结构,比如树形菜单数据、多级分类数据等,从中提取特定类型的元素是常见的开发需求。比如我们需要从多层级的人员数据中,筛选出所有类型为管理员的人员信息,或者从嵌套的商品分类中提取所有类型为虚拟商品的条目。
核心实现思路
提取嵌套对象数组中的特定类型元素,核心逻辑可以分为三步:
- 遍历当前层级的数组元素
- 对每个元素进行类型判断,符合要求的存入结果数组
- 如果元素包含子数组,递归处理子数组
基础实现示例
假设我们有如下嵌套对象数组,需要提取所有type为admin的元素:
// 示例嵌套对象数组
const nestedData = [
{
id: 1,
name: '张三',
type: 'user',
children: [
{ id: 11, name: '李四', type: 'admin', children: [] },
{ id: 12, name: '王五', type: 'user', children: [
{ id: 121, name: '赵六', type: 'admin', children: [] }
]}
]
},
{
id: 2,
name: '孙七',
type: 'admin',
children: []
}
];
下面是实现提取功能的函数:
/**
* 从嵌套对象数组中提取特定类型元素
* @param {Array} arr 待处理的嵌套数组
* @param {String} targetType 目标类型值
* @param {String} typeKey 类型字段名,默认是type
* @param {String} childrenKey 子数组字段名,默认是children
* @returns {Array} 提取到的符合条件的元素数组
*/
function extractByType(arr, targetType, typeKey = 'type', childrenKey = 'children') {
let result = [];
// 遍历当前层级数组
for (let item of arr) {
// 判断当前元素类型是否符合要求
if (item[typeKey] === targetType) {
result.push(item);
}
// 如果存在子数组,递归处理
if (item[childrenKey] && Array.isArray(item[childrenKey])) {
const childResult = extractByType(item[childrenKey], targetType, typeKey, childrenKey);
result = result.concat(childResult);
}
}
return result;
}
// 调用函数提取type为admin的元素
const adminList = extractByType(nestedData, 'admin');
console.log(adminList);
// 输出结果包含id为11、121、2的三个admin元素
特殊情况处理
子数组字段名不固定
如果不同的数据结构中,子数组的字段名不是固定的children,可以通过参数传入对应的字段名,上面的函数已经支持该场景,调用时传入第三个和第四个参数即可:
// 子数组字段名为subItems的场景
const anotherData = [
{ id: 1, type: 'admin', subItems: [
{ id: 11, type: 'user', subItems: [] }
]}
];
const result = extractByType(anotherData, 'admin', 'type', 'subItems');
console.log(result); // 输出id为1的元素
类型判断规则更复杂
如果类型判断不是简单的相等匹配,比如需要判断类型包含某个关键字,或者符合某种正则规则,可以修改判断逻辑:
/**
* 支持自定义判断规则的提取函数
* @param {Array} arr 待处理数组
* @param {Function} matchFn 自定义匹配函数,接收元素返回布尔值
* @param {String} childrenKey 子数组字段名
* @returns {Array} 匹配的元素数组
*/
function extractByCustomRule(arr, matchFn, childrenKey = 'children') {
let result = [];
for (let item of arr) {
if (matchFn(item)) {
result.push(item);
}
if (item[childrenKey] && Array.isArray(item[childrenKey])) {
const childResult = extractByCustomRule(item[childrenKey], matchFn, childrenKey);
result = result.concat(childResult);
}
}
return result;
}
// 提取type包含admin关键字的元素
const matchedList = extractByCustomRule(nestedData, (item) => {
return item.type && item.type.includes('admin');
});
console.log(matchedList);
性能优化建议
如果处理的嵌套数组层级非常深、数据量很大,递归可能会出现栈溢出问题,可以考虑使用栈或队列的迭代方式实现:
function extractByTypeIterative(arr, targetType, typeKey = 'type', childrenKey = 'children') {
const result = [];
const stack = [...arr]; // 初始栈为第一层数组
while (stack.length > 0) {
const current = stack.pop();
if (current[typeKey] === targetType) {
result.push(current);
}
// 将子数组元素加入栈
if (current[childrenKey] && Array.isArray(current[childrenKey])) {
stack.push(...current[childrenKey]);
}
}
return result;
}
这种方式用循环代替递归,避免了深层级递归导致的栈溢出问题,适合处理超大数据量的场景。
JavaScript嵌套对象数组数组过滤类型判断数据提取修改时间:2026-06-24 10:09:23