新闻中心
从深度嵌套数组中高效提取特定类型对象

本文详细介绍了如何使用迭代堆栈(stack)方法,从复杂的深度嵌套对象数组中提取所有具有特定type属性的对象。该教程通过清晰的算法步骤和typescript代码示例,演示了如何有效遍历多层数据结构,避免了递归可能导致的栈溢出问题,适用于处理层级不定的数据。
在现代Web应用开发中,我们经常需要处理复杂的数据结构,其中包含多层嵌套的对象和数组。例如,一个UI组件树、一个文档对象模型(DOM)的表示,或者像本例中所示的具有items子属性的“组”结构。当我们需要从这种深度嵌套的数据中筛选出所有满足特定条件的元素时,传统的数组方法(如filter)往往力不从心,因为它只能处理当前层级的元素。
本教程将提供一种健壮且高效的方法来解决这个问题:使用迭代式的深度优先遍历(DFS)结合堆栈(Stack)数据结构。这种方法能够确保遍历到所有层级的元素,并且避免了递归深度过大可能导致的栈溢出问题。
挑战:深度嵌套数据中的特定元素提取
假设我们有一个JSON数组,其中每个对象可能包含一个type属性,并且一些对象还可能包含一个items数组,而items数组中的元素又可能遵循相同的结构,形成一个深层嵌套的树状结构。我们的目标是从这个复杂的结构中找出所有type属性值为 "text" 的对象。
以下是一个示例数据结构:
万相营造
阿里妈妈推出的AI电商营销工具
168
查看详情
[
{
"index": 3,
"uid": "188960ecb29_00562b0c",
"type": "group",
"items": [
{
"uid": "18895f59b1a_2c5a5c7a",
"type": "text", // 这是一个目标对象
"text": ["abc"]
},
{
"index": 1,
"type": "group",
"items": [
{
"uid": "18895ecc7c7_2d5440b6",
"type": "text", // 另一个目标对象
"text": ["xyz"]
}
]
}
]
}
// ... 更多类似的嵌套结构
]解决方案:迭代式堆栈遍历算法
为了遍历所有层级的元素,我们可以采用类似深度优先搜索(DFS)的策略,但通过显式管理一个堆栈来避免函数调用栈的限制。
算法步骤
- 初始化结果数组: 创建一个空数组,用于存储所有符合条件的对象。
-
初始化堆栈:
创建一个堆栈,并将输入数组中的所有顶层元素压入堆栈。 -
循环遍历: 当堆栈不为空时,重复以下操作:
- 弹出元素: 从堆栈顶部弹出一个当前元素。
- 条件检查: 检查当前元素的 type 属性是否与目标类型(例如 "text")匹配。如果匹配,则将此元素添加到结果数组中。
- 压入子元素: 如果当前元素包含一个 items 属性(表示它有子元素),则将 items 数组中的所有子元素压入堆栈。这样可以确保在下一轮循环中,这些子元素也会被处理。
- 返回结果: 循环结束后,返回包含所有符合条件对象的结果数组。
TypeScript 实现示例
下面是基于上述算法的 TypeScript 实现代码。为了方便演示,我们假设 data 是一个全局或传入的数组变量。
// 假设这是我们的输入数据结构
interface NestedItem {
uid: string;
type: string;
items?: NestedItem[]; // 子元素可能也是NestedItem类型
[key: string]: any; // 允许其他任意属性
}
const data: NestedItem[] = [
{
"index": 3,
"uid": "188960ecb29_00562b0c",
"x": 18.65,
"y": 44.14,
"width": 180.14,
"height": 53.33,
"items": [
{
"uid": "18895f59b1a_2c5a5c7a",
"locked": false,
"rotation": 0,
"type": "text", // 目标对象
"text": ["abc"],
"x": 154.37,
"y": 0,
"width": 25.76,
"height": 20.90
},
{
"index": 1,
"uid": "1889607cfdf_091e59ca",
"x": 0,
"y": 32.43,
"width": 22.17,
"height": 20.90,
"items": [
{
"uid": "18895ecc7c7_2d5440b6",
"locked": false,
"rotation": 0,
"type": "text", // 目标对象
"text": ["xyz"],
"x": 0,
"y": 0,
"width": 22.17,
"height": 20.90
}
],
"type": "group",
"rotation": 0
},
{
"index": 2,
"uid": "188960e945c_35ab99fa",
"x": 44.10,
"y": 15.56,
"width": 56.72,
"height": 35.17,
"items": [
{
"uid": "18896072844_1298562b",
"locked": false,
"rotation": 0,
"type": "text", // 目标对象
"text": ["group"],
"x": 15.56,
"y": 14.27,
"width": 41.15,
"height": 20.90
},
{
"index": 3,
"uid": "188960e5f49_2341c362",
"x": 0,
"y": 0,
"width": 29.80,
"height": 20.90,
"items": [
{
"uid": "188958badfe_3a73220b",
"locked": false,
"rotation": 0,
"type": "text", // 目标对象
"text": ["Text"],
"x": 0,
"y": 0,
"width": 29.80,
"height": 20.90
}
],
"type": "group",
"rotation": 0
}
],
"type": "group",
"rotation": 0
}
],
"type": "group",
"rotation": 0
}
];
/**
* 从深度嵌套的数组中提取所有指定类型的对象。
* @param targetType 要查找的对象类型字符串。
* @param initialData 初始的嵌套数据数组。
* @returns 包含所有匹配对象的数组。
*/
const getSpecificType = (targetType: string, initialData: NestedItem[]): NestedItem[] => {
const result: NestedItem[] = []; // 存储结果的数组
// 使用展开运算符将初始数据复制到堆栈中,避免修改原始数据
const stack: NestedItem[] = [...initialData];
// 当堆栈不为空时,持续处理
while (stack.length > 0) {
const current = stack.pop(); // 弹出堆栈顶部的元素
// 检查弹出的元素是否有效,防止undefined或null
if (!current) {
continue;
}
// 如果当前元素的type属性与目标类型匹配,则将其添加到结果数组
if (current.type === targetType) {
result.push(current);
}
// 如果当前元素有子元素(即有items属性),则将这些子元素压入堆栈
// 使用 ?? [] 确保即使items为null或undefined也能安全操作
if (current.items && current.items.length > 0) {
stack.push(...current.items);
}
}
return result; // 返回所有找到的匹配对象
};
// 调用函数并打印结果
const textObjects = getSpecificType("text", data);
console.log(textObjects);
/* 预期输出示例 (部分):
[
{ uid: '18895f59b1a_2c5a5c7a', locked: false, rotation: 0, type: 'text', text: [ 'abc' ], ... },
{ uid: '18895ecc7c7_2d5440b6', locked: false, rotation: 0, type: 'text', text: [ 'xyz' ], ... },
{ uid: '18896072844_1298562b', locked: false, rotation: 0, type: 'text', text: [ 'group' ], ... },
{ uid: '188958badfe_3a73220b', locked: false, rotation: 0, type: 'text', text: [ 'Text' ], ... }
]
*/你可以在 [TypeScript Playground](https://www.php.cn/link/603a99469d867c85df8c8e940f3ed965
以上就是从深度嵌套数组中高效提取特定类型对象的详细内容,更多请关注其它相关文章!
# 网站建设锚文件
# 弹出
# 则将
# 复选框
# 是一个
# 是从
# 自定义
# 青岛短视频seo厂家
# 宁波网站建设技术方案
# 组中
# 江苏企业网站seo
# 北塘区网络推广营销公司
# 避暑广告网站推广费用
# 洛阳建设网站制作
# 大庆seo软件成功案例
# 台州招聘网站建设
# 沈阳全网推广招聘网站
# css
# 遍历
# 递归
# 数据结构
# yy
# json数组
# 应用开发
# ai
# 栈
# gmp
# qq
# typescript
# go
# json
# git
# js
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
铁路12306官网网页端快速入口 铁路12306官方首页登录教程
Python多版本共存与虚拟环境管理深度指南
Win10磁盘清理工具在哪 Win10打开并使用磁盘清理【教程】
如何使用Go和Martini动态服务解码后的图片
Composer如何解决json扩展缺失的错误
Go语言中高效处理x-www-form-urlencoded表单数据
AO3最新入口2025公告_AO3中文官网合集
192.168.1.1管理中心入口 192.168.1.1路由器网页设置平台
支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
React Router v6 教程:构建认证保护的私有路由与重定向策略
iwriter统一登录平台 iwrite账号密码登录页面
J*aScript动态修改指定div内所有a标签样式指南
蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址
b站赚钱渠道_b站收益来源
必由学网页版入口 必由学官方平台直接访问
如何在 Windows 11 中启动游戏手柄设置
快手网页版在线登录 快手网页版官网入口快速访问
VS Code远程开发时如何处理文件权限问题
在J*a中如何开发简易仓库管理与库存统计_仓库管理库存统计项目实战解析
百度浏览器字体显示异常偏小_百度浏览器字体渲染修复方案
AO3官方在线访问地址 Archive of Our Own最新镜像合集
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
如何有效阻止外部脚本意外修改内联样式的高度属性
CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整
一加 Nord 5 隐私权限异常_一加 Nord 5 系统安全优化
大麦的“候补”是什么意思 大麦候补购票规则【详解】
Google翻译怎么语音输入_Google翻译语音输入功能使用与设置方法
字由网在线版登录地址 字由网网页版安全入口
C++如何解决segmentation fault_C++段错误调试与原因分析
精准捕获:如何在页面中监听除特定元素外的所有点击事件
谷歌google账号注册详细步骤 谷歌账号注册官方教程
Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】
高德地图沿途添加点失败如何解决 高德多点规划方法
Win10如何清理注册表垃圾 Win10注册表维护与优化指南【慎用】
单12V-2×6实现为RTX 5090供电750W!甚至都没敢跑分
搜狗浏览器如何使用密码生成器创建强密码 搜狗浏览器内置密码安全工具
Win10系统服务哪些可以禁用 Win10安全优化服务列表【干货】
极兔快递快件信息查询系统 极兔快递官网运单号追踪
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
顺丰快件物流信息 官方网站查询入口
qq游戏跨平台入口_qq游戏多设备同步登录
响应式容器内容自动缩放与宽高比维持教程
在命令行怎么运行html项目_命令行运行html项目方法【教程】
b站怎么看视频的弹幕数量_b站弹幕数量查看方法
处理动态列数据:J*a ArrayList的正确初始化与字符累加教程
Pandas DataFrame 多条件优先级排序与排名
lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法


2025-10-29
浏览次数:次
返回列表
创建一个堆栈,并将输入数组中的所有顶层元素压入堆栈。