杨利杰YJlio博客头图

ArkTS数组遍历与筛选

前言:一组工单要先说清操作目的

大家好,我是杨利杰 YJlio。

上一篇把一条工单组织成对象。这篇把记录放进数组,分别练习逐项处理、提取标题、筛选未完成记录和查找编号。

我的做法是先问“需要什么结果”,再选择 for...of、map、filter 或 find。这是 HarmonyOS 7.0 学习笔记第 07 篇。

返回新数组不等于深拷贝;查找结果也可能不存在。

环境项实际记录
DevEco Studio待填写
SDK/API与ArkTS工具链待填写
工程当前 ArkTS 练习工程
数据来源内存中的三条示例记录

本文配图为知识示意图。示例没有连接网络、数据库或真实工单系统,也没有预先填写本机日志与构建结果。

一、先定义数组元素的结构

为集中练习数组,我使用只包含列表所需字段的 TicketListItem。它与上一篇完整的 Ticket 分开命名,不把三字段对象当作五字段模型。

三条工单与元素类型

enum TicketStatus {
  New = 0,
  Processing = 1,
  Resolved = 2
}

interface TicketListItem {
  id: string;
  title: string;
  status: TicketStatus;
}

const tickets: TicketListItem[] = [
  { id: 'T-1001', title: '无法连接办公网络', status: TicketStatus.New },
  { id: 'T-1002', title: '打印机无法出纸', status: TicketStatus.Processing },
  { id: 'T-1003', title: '账号已解锁', status: TicketStatus.Resolved }
];

TicketListItem[] 说明元素的类型。标识、标题和状态都来自本篇练习数据;外部数据仍需解析和校验。

这里使用普通数组,不是跨并发任务的 collections.Array。华为共享容器说明列出了共享容器与原生容器的区别,阅读接口时要先确认是哪一种。

二、for…of:逐项执行动作

需要记录每条工单或累计结果时,我先使用能直接读出目的的循环。

for...of逐项执行动作

for (const item of tickets) {
  console.info(`${item.id}: ${item.title}`);
}

循环每次取得当前元素,再执行方法体。这里仅输出文本,不修改元素,也不改变数组结构。

这不是已经运行过的日志截图。实际执行位置按工程组织方式确定,构建与日志记录都需要本机完成。

三、map:从元素生成新的值

只需要标题列表时,我用 map 表达“每条工单转成一个标题”。

map转换为新数组

const titles: string[] = tickets.map(
  (item: TicketListItem): string => item.title
);

本例是稠密数组,回调只读取标题,结果应按原顺序包含三个标题。空数组映射后仍是空数组。

这个新数组保存字符串,没有继续保留完整工单字段。如果详情页需要标识、状态等信息,应保留完整对象,不能从一份标题数组猜回记录。

map 本身不要求修改源数组,但回调仍可以产生副作用。本篇保持回调只读,避免把转换和修改混在一起。

四、filter:保留符合条件的记录

要得到未完成工单,我用状态条件排除 Resolved,而不是删除原数组中的元素。

filter保留匹配元素

const active: TicketListItem[] = tickets.filter(
  (item: TicketListItem): boolean => item.status !== TicketStatus.Resolved
);

按示例推导,结果保留 T-1001 和 T-1002,顺序与原数组一致。它不会负责排序;没有匹配项时,结果可以是空数组。

这些是代码阅读得到的预期,不是本机运行证据。实际数量与内容仍需记录。

筛选结果为空通常是正常业务结果,不应假设至少有一条记录。

五、find:找到第一条,或返回 undefined

查询特定标识时,我用 find。它返回第一个匹配元素,找不到时返回 undefined。

find与未找到分支

const selected: TicketListItem | undefined = tickets.find(
  (item: TicketListItem): boolean => item.id === 'T-1002'
);

if (selected === undefined) {
  console.info('未找到工单');
} else {
  console.info(selected.title);
}

查找第一条匹配项不等于检查标识唯一。如果重复标识会造成问题,需要在数据层另外保证唯一性。

我也会用不存在的 T-9999 练习未找到分支。不要为了消除提示使用非空断言,否则无记录场景仍然没有处理。

六、先筛选,再转换显示文本

当目标是“未完成工单的显示文本”,可以把筛选和转换按步骤连接起来。

先filter再map

const labels: string[] = active.map(
  (item: TicketListItem): string => `${item.id} - ${item.title}`
);

for (const label of labels) {
  console.info(label);
}

这里沿用前面得到的 active。筛选负责决定保留哪些记录,映射负责决定显示哪些文字;每一步的结果类型都明确。

不要把这段文本生成逻辑当成 ArkUI 列表渲染。它还没有接入页面状态或组件,后续章节再连接界面。

七、新数组与原对象可能共享引用

我会把“数组容器不同”和“内部对象是否独立”分开观察,避免筛选后误改原记录。

新数组不等于深拷贝

在本例中,filter 创建新的数组容器,保留下来的仍是原对象;find 返回的也是原数组中的匹配对象。读取没问题,修改属性则可能反映到源记录。

因此,“操作前后 tickets.length 没变”只能说明数量没变,不能证明所有对象属性都没有变化。观察源数据时,数量、顺序和字段值都要看。

push、splice 和普通数组的 sort 会改变数组。本篇不在原数组上进行这些操作;需要排序时应明确规则和复制范围。浅复制容器仍不会自动深拷贝对象。

不要只比较数组长度,就认定源数据完全没有变化。

八、记录空结果、顺序与字段变化

本机实验时,我会先记录原数组,再逐项运行转换、筛选和查找,最后比较数量、顺序和字段。

数组操作核验记录

  1. 保留模板,在合适的逻辑文件或已有执行位置加入示例。
  2. 构建后记录工具链版本与结果。
  3. 记录原数组标识顺序和字段值。
  4. 运行 map、filter、find,逐项保存真实输出。
  5. 查询不存在编号,确认走未找到分支。
  6. 比较源数组数量、顺序和字段;不要在回调中增加修改操作。
操作本篇预期本机实际记录
提取标题按原顺序得到三个标题待填写
排除已解决状态保留 T-1001、T-1002待填写
查找 T-1002返回该记录待填写
查找 T-9999undefined待填写
比较源数据本例只读回调不修改源数据待填写

如果普通数组操作得到正确结果,页面却没刷新,还要检查当前 ArkUI 状态管理机制。类型正确、集合结果正确与界面更新是不同的核验项。

学习总结

这篇我用一组工单分别练习遍历、转换、筛选和查找。选择方法前先明确结果类型,再处理空数组、未找到和对象引用。

发布前补齐本机日志和构建记录。下一篇使用条件分支准备加载、错误、空数据和有数据四种列表状态。

参考资料

  1. 华为开发者联盟:ArkTS 语言概览
  2. 华为开发者文档:共享容器与原生容器的区别
  3. ECMAScript 规范:Array.prototype 方法

声明:本文为学习示例与练习方法,配图为知识示意图;实际语法、接口支持、日志和构建结果以当前工程、工具链及官方文档为准。

分隔线

返回顶部

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐