从对象数组提取各类型首项的JS实现未达预期
原代码运行不符合预期的核心原因
- 校验对象完全错配:
devicesList从初始化到代码结束,从来没有存储过任何device.Type的标识值,仅被用来承载map方法的返回结果,导致devicesList.includes(device.Type)永远返回false,所有设备都会被判定为未出现过,直接返回。 - 数组结构错位:
devicesList.push(measurements.map(...))的写法,会把map生成的整个结果数组当作单个元素塞进devicesList,最终devicesList是一层包裹了结果的二维结构,并不是你想要的平铺的设备列表。 - 执行时机错位:JS的
Array.map会一次性遍历完所有输入元素,统一生成返回值。遍历过程中你对devicesList的修改,完全不会影响map回调里的判断逻辑——回调执行时devicesList还是初始的空数组,类型校验从一开始就没有生效。
适配需求的正确实现
需求是保留每个设备类型在原数组中首次出现的条目,直接用集合维护已出现的类型标识即可,代码如下:
LastReadingOfEach(measurements) { // 用Set存储已经遇到过的设备类型,查询效率比原生数组更高 const appearedTypes = new Set(); const devicesList = measurements.filter((device) => { const currentType = device.Type; // 没遇到过的类型:保留当前设备,把类型标记为已出现 if (!appearedTypes.has(currentType)) { appearedTypes.add(currentType); return true; } // 已经遇到过的同类型设备:直接过滤 console.log("removed :", device); return false; }); console.log("devicesList :", devicesList); // 按需添加return devicesList,把筛选结果带出方法 }
实现逻辑说明
- 所有判断都围绕设备Type值展开,不会出现校验对象存错导致的逻辑失效
- filter方法逐元素实时判断,每遍历一个设备就立即检查类型是否已经出现过,完全匹配“保留各类型首次出现项”的规则
- 最终输出的是一维的设备对象数组,结构清晰,不会出现嵌套包裹的问题
内容的提问来源于stack exchange,提问作者GHOST
相关产品推荐
相关产品推荐

