IndexOf(elem)始终返回-1问题排查及替代方案咨询
问题分析与解决方案
核心问题:你忽略了「引用类型的相等判断规则」
IndexOf() 方法是基于严格相等(===)来匹配元素的。如果你的 origPlan 和 finalPlan 里的元素是对象类型(比如 {id: 1, name: 'xxx'} 这类),哪怕两个对象的内容完全一样,它们的内存引用也是不同的,elem === finalPlan里的对象 会返回 false,所以 IndexOf(elem) 永远找不到匹配项,只能返回 -1。
替代 IndexOf 的完美方案:findIndex()
findIndex() 完全符合你的需求——找不到元素时返回 -1,关键是它支持自定义判断逻辑,你可以根据对象的唯一标识属性(比如 id、name 等)来判断元素是否存在,而不是依赖内存引用。
举个修正后的代码示例(假设你的元素有唯一的 name 属性):
const origPlan = [{name: '早餐'}, {name: '早餐'}, {name: '午餐'}]; const finalPlan = []; for (const elem of origPlan) { // 用findIndex自定义匹配规则:比较name属性 const existIndex = finalPlan.findIndex(item => item.name === elem.name); if (existIndex !== -1) { finalPlan[existIndex].count++; } else { finalPlan.push({...elem, count: 1}); } }
更高效的统计方案:用临时对象先计数
如果你的数据量较大,反复用 findIndex 遍历 finalPlan 会有点低效,推荐先用一个临时对象统计数量,再转换成目标格式:
const origPlan = [{name: '早餐'}, {name: '早餐'}, {name: '午餐'}]; const countMap = {}; // 第一步:统计每个项的数量 for (const elem of origPlan) { const key = elem.name; // 用唯一属性当键 countMap[key] = (countMap[key] || 0) + 1; } // 第二步:转换成finalPlan格式 const finalPlan = Object.entries(countMap).map(([name, count]) => ({ name, count }));
补充说明
除了 findIndex(),你也可以用 some() 或 find() 来判断元素是否存在,但 findIndex() 直接返回索引,最贴合你原本的逻辑需求,不需要额外处理。
内容的提问来源于stack exchange,提问作者chris cozzens
相关产品推荐
相关产品推荐

