Angular数组添加对象前重复校验失效问题排查
Angular数组对象重复校验总是返回-1?看这里!
嘿,我太懂你这个烦恼了——之前我也踩过一模一样的坑!你遇到的问题根源其实很简单:对象是引用类型,你用indexOf这种依赖严格相等(===)的方法去校验重复时,哪怕两个对象的所有属性都完全一样,只要它们不是内存里的同一个引用,indexOf就会返回-1,直接把重复对象塞进数组里。
先给你拆解下问题:你定义的StressTestAnalysis是一个接口,results是它的数组。当你尝试用this.results.indexOf(newItem)判断是否存在时,本质是在比较两个对象的内存地址,而不是它们的属性内容——这就是为什么明明有重复对象,却总是返回-1。
解决方案:基于属性判断重复,而不是引用
1. 用唯一标识属性校验(推荐最高效)
先找StressTestAnalysis里的唯一属性,比如seriesName(看起来像是系列名称,大概率是唯一的),然后用findIndex来检查数组里是否已经存在相同标识的对象。
修改你的stressResults setter代码如下:
@Input() set stressResults(value: Array<StressTestAnalysis>) { if (!value) return; value.forEach(newItem => { // 检查数组中是否已有相同seriesName的对象 const isDuplicate = this.results.findIndex(existingItem => existingItem.seriesName === newItem.seriesName ) !== -1; if (!isDuplicate) { this.results.push(newItem); } }); }
如果没有单一的唯一属性,你可以组合多个关键属性来判断,比如同时比较curlevel和seriesName:
const isDuplicate = this.results.findIndex(existingItem => existingItem.curlevel === newItem.curlevel && existingItem.seriesName === newItem.seriesName ) !== -1;
2. 完全比较所有属性(仅当必要时使用)
如果必须确保对象的每一个属性都完全一致才判定为重复,可以写一个工具函数来做深比较。注意:这种方式性能不如用唯一标识,而且要记得把父接口GraphConfiguration的属性也加入比较!
private isStressTestAnalysisEqual( a: StressTestAnalysis, b: StressTestAnalysis ): boolean { // 先判断引用是否相同,相同直接返回true if (a === b) return true; // 比较所有属性(包括继承自GraphConfiguration的属性) return a.curlevel === b.curlevel && a.decrease === b.decrease && a.increase === b.increase && // 数组比较:如果顺序不重要,可以先排序再转字符串 JSON.stringify(a.yaxis.sort()) === JSON.stringify(b.yaxis.sort()) && JSON.stringify(a.data.sort()) === JSON.stringify(b.data.sort()) && a.seriesName === b.seriesName && a.color === b.color && // 替换成GraphConfiguration里的实际属性,比如: a.title === b.title && a.xAxisLabel === b.xAxisLabel; } // 在setter里使用: @Input() set stressResults(value: Array<StressTestAnalysis>) { if (!value) return; value.forEach(newItem => { const isDuplicate = this.results.some(existingItem => this.isStressTestAnalysisEqual(existingItem, newItem) ); if (!isDuplicate) { this.results.push(newItem); } }); }
小提醒
- 尽量用唯一标识属性来判断,性能更好也更易维护;
- 如果用
JSON.stringify比较数组,要注意数组元素的顺序——如果顺序不同但值相同会被判定为不相等,这时候可以先排序再比较; - 别忘了
GraphConfiguration里的属性,一定要加入比较逻辑,不然会出现“部分属性不同但被判定为重复”或者相反的问题。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

