列表移除元素重索引致原始索引失效,求最优处理算法
批量按原始索引删除列表元素的最优处理思路
核心问题
你当前的代码会出错,因为删除列表元素后,后续元素的索引会自动前移。比如先删索引2的元素,原来索引5的元素会变成索引4,这时候再用原始的5去删除,要么越界要么删错元素。
最优处理思路
倒序删除是关键
先把要删除的索引列表去重后按从大到小排序。先删大索引的元素,这样不会影响小索引元素的位置——大索引元素在小索引后面,删除它不会改变前面元素的索引值,所有原始索引都能精准对应到要删的元素。加一层边界校验
提前过滤掉超出列表范围的无效索引,避免运行时抛出索引越界异常。比如确保索引≥0且小于对应列表的长度。执行批量删除
按排序后的索引依次对5个列表执行删除操作,此时每个操作都基于原始索引逻辑,不会出现偏移。
修正后的代码示例
' 去重并按降序排序索引列表 arrIntIndexesOfJobsThatWillBeKilled = arrIntIndexesOfJobsThatWillBeKilled.Distinct().OrderByDescending(Function(x) x).ToList() If arrIntIndexesOfJobsThatWillBeKilled.Count > 0 Then ' 计算所有列表的最大有效索引,过滤无效索引 Dim maxValidIndex = Math.Min( arrStrJobDescription2.Count - 1, arrStrPNDirectories2.Count - 1, arrIntJobIDDirectories2.Count - 1, arrStrSubDirectories2.Count - 1, arrStrNCFile2.Count - 1 ) arrIntIndexesOfJobsThatWillBeKilled = arrIntIndexesOfJobsThatWillBeKilled.Where(Function(idx) idx >= 0 AndAlso idx <= maxValidIndex).ToList() ' 倒序删除,保证原始索引有效 For Each Job As Integer In arrIntIndexesOfJobsThatWillBeKilled arrStrJobDescription2.RemoveAt(Job) arrStrPNDirectories2.RemoveAt(Job) arrIntJobIDDirectories2.RemoveAt(Job) arrStrSubDirectories2.RemoveAt(Job) arrStrNCFile2.RemoveAt(Job) Next End If
替代思路(适合删除元素较多的场景)
如果允许创建新列表,也可以通过筛选保留不需要删除的元素来实现,逻辑更简单:
If arrIntIndexesOfJobsThatWillBeKilled.Count > 0 Then Dim keepIndexes = Enumerable.Range(0, arrStrJobDescription2.Count).Except(arrIntIndexesOfJobsThatWillBeKilled).ToList() arrStrJobDescription2 = keepIndexes.Select(Function(idx) arrStrJobDescription2(idx)).ToList() arrStrPNDirectories2 = keepIndexes.Select(Function(idx) arrStrPNDirectories2(idx)).ToList() arrIntJobIDDirectories2 = keepIndexes.Select(Function(idx) arrIntJobIDDirectories2(idx)).ToList() arrStrSubDirectories2 = keepIndexes.Select(Function(idx) arrStrSubDirectories2(idx)).ToList() arrStrNCFile2 = keepIndexes.Select(Function(idx) arrStrNCFile2(idx)).ToList() End If
这种方式不需要考虑索引偏移,但会创建新列表,内存占用略高,适合要删除的元素占比大的情况。
内容的提问来源于stack exchange,提问作者Daniel Santos
相关产品推荐
相关产品推荐

