对象列表中按优先级条件查找元素索引的优化方案咨询
最优实现方案
原有实现的性能瓶颈是:每遍历一个MainArray的元素,最多需要遍历两次orders数组,整体时间复杂度为O(M*N)(M为MainArray长度,N为orders长度),数组长度较大时性能损耗明显。推荐优先使用预构建索引映射的方案,时间复杂度可降低至O(M+N):
方案A:预构建优先级索引映射(推荐,适配所有场景,大数组性能提升显著)
提前遍历一次orders数组,为每个slot值存储优先级最高的对应索引:存在WAITING状态的项时存对应索引,否则存第一个匹配slot的索引,后续查询直接走O(1)的哈希表查找。
// 第一步:预构建slot到最高优先级索引的映射,仅需执行一次 const slotIndexMap = new Map() orders?.forEach((item, index) => { const currentSlot = item.slot // 仅当映射无当前slot记录 或 当前项是WAITING状态且已有记录不是WAITING时更新映射 if ( !slotIndexMap.has(currentSlot) || (item.status === 'WAITING' && orders[slotIndexMap.get(currentSlot)].status !== 'WAITING') ) { slotIndexMap.set(currentSlot, index) } }) // 第二步:遍历MainArray直接查询映射表即可 const result = MainArray.map(x => slotIndexMap.get(x) ?? -1)
优势:
- 性能更高:
orders仅需遍历一次,后续所有查询都是O(1)复杂度,数组越长性能优势越明显 - 可复用性强:如果这段查找逻辑需要多次执行,仅需构建一次映射表即可
- 逻辑拆分清晰:预处理和业务查询分离,便于后续维护
方案B:单次查找简化(适用于orders长度极小的临时场景)
如果orders长度很小(低于50),性能差异可以忽略,可以直接简化原有写法,减少冗余代码:
MainArray.map(x => { let waitingIndex = -1 let normalIndex = -1 // 一次遍历orders同时记录两种状态的索引 orders?.some((item, idx) => { if (item.slot === x) { if (item.status === 'WAITING') { waitingIndex = idx return true // 找到最高优先级项直接终止遍历 } normalIndex = idx } return false }) return waitingIndex !== -1 ? waitingIndex : normalIndex })
内容的提问来源于stack exchange,提问作者Amin Noura
相关产品推荐
相关产品推荐

