Angular4中高效实现API返回数组的唯一数据列表更新方案问询
高效实现Angular 4中唯一值列表的增量更新
嘿,你的现有代码确实能实现需求,但嵌套循环在数据量变大的时候效率会打折扣——用Set来优化完全是正确的思路,可能之前只是没把数据处理和去重的步骤结合好。我来给你梳理几个更高效的实现方式:
核心优化思路
之前的嵌套循环判断重复的时间复杂度是O(n*m)(n是API返回数据长度,m是现有列表长度),而用Set存储已存在的time值后,判断重复的操作会变成O(1),整体时间复杂度降到O(n+m),数据量大的时候差异会非常明显。
方案一:拆分处理+过滤去重
先把API返回的数据转换成你需要的格式并筛选有效项,再结合Set筛选出当前列表中没有的新数据:
// 1. 先处理API返回数据,筛选并转换为目标格式 const processedItems = response.filter(item => { const valueParts = item.value.split('_'); // 只保留能拆分为两部分且第二部分长度为2的项 return valueParts.length === 2 && valueParts[1].length === 2; }).map(item => { const valueParts = item.value.split('_'); return { id: valueParts[0], time: valueParts[1] }; }); // 2. 用Set记录现有列表中的time值,快速判断重复 const existingTimeSet = new Set(this.listData.map(item => item.time)); // 筛选出不在现有列表中的新项 const newUniqueItems = processedItems.filter(item => { if (!existingTimeSet.has(item.time)) { existingTimeSet.add(item.time); return true; } return false; }); // 3. 仅新增数据,不修改原有列表 this.listData.push(...newUniqueItems);
方案二:单次遍历完成处理(更高效)
如果想减少遍历次数,可以把数据处理、筛选、去重合并成一次遍历,进一步提升性能:
const existingTimeSet = new Set(this.listData.map(item => item.time)); const newUniqueItems: {id: string, time: string}[] = []; response.forEach(item => { const valueParts = item.value.split('_'); // 先判断数据格式是否符合要求 if (valueParts.length === 2 && valueParts[1].length === 2) { const newItem = { id: valueParts[0], time: valueParts[1] }; // 检查是否已存在,不存在则加入集合和新数组 if (!existingTimeSet.has(newItem.time)) { existingTimeSet.add(newItem.time); newUniqueItems.push(newItem); } } }); // 增量更新列表 this.listData.push(...newUniqueItems);
关于定时API调用的注意事项
你提到需要定时调用API且仅在有新数据时更新列表,上面的方案已经天然满足这个需求:每次调用API时,我们都是基于当前listData的time集合去筛选新数据,只有真正新增的项才会被加入列表,不会重复添加或修改已有内容。
如果之前尝试array.filter和new Set没成功,大概率是没结合现有列表的状态——比如只对新返回的数组去重,却没考虑和已有列表的重复项,上面的方案完美解决了这个问题。
内容的提问来源于stack exchange,提问作者Tony Roczz
相关产品推荐
相关产品推荐

