我有一个要从C#中的有序集合中删除的项目列表。
最好的方法是什么?
如果我删除了中间的项目,索引会更改,但如果我想删除多个项目,该怎么办?
答案 0 :(得分:5)
要避免索引更改,请从最后开始,然后返回索引0。
这些方面的东西:
for(int i = myList.Count - 1; i >= 0; i++)
{
if(NeedToDelete(myList[i]))
{
myList.RemoveAt(i);
}
}
答案 1 :(得分:1)
该系列的类型是什么?如果它继承自ICollection,您只需在要删除的项列表上运行循环,然后在集合上调用.Remove()
方法。
例如:
object[] itemsToDelete = GetObjectsToDeleteFromSomewhere();
ICollection<object> orderedCollection = GetCollectionFromSomewhere();
foreach (object item in itemsToDelete)
{
orderedCollection.Remove(item);
}
答案 2 :(得分:1)
如果集合是List<T>
,您还可以使用RemoveAll方法:
list.RemoveAll(x => otherlist.Contains(x));
答案 3 :(得分:0)
假设要删除的项目列表相对较短,您可以先对目标列表进行排序。然后遍历源列表并在目标列表中保留一个索引,该索引对应于您删除的项目。
假设源列表为haystack
,要删除的项目列表为needle
:
needle.Sort(); // not needed if it's known that `needle` is sorted
// haystack is known to be sorted
haystackIdx = 0;
needleIdx = 0;
while (needleIdx < needle.Count && haystackIdx < haystack.Count)
{
if (haystack[haystackIdx] < needle[needleIdx])
haystackIdx++;
else if (haystack[haystackIdx] > needle[needleIdx])
needleIdx++;
else
haystack.RemoveAt(haystackIdx);
}
这样,只有haystack
和needle
的遍历,加上needle
的排序时间,前提是删除为O(1)
(通常是链接列表和类似集合的案例)。如果集合是List<...>
,由于数据移位,删除将需要O(collection size)
,因此您最好从两个集合的末尾开始并移至开头:
needle.Sort(); // not needed if it's known that `needle` is sorted
// haystack is known to be sorted
haystackIdx = haystack.Count - 1;
needleIdx = needle.Count - 1;
while (needleIdx >= 0 && haystackIdx >= 0)
{
if (haystack[haystackIdx] > needle[needleIdx])
haystackIdx--;
else if (haystack[haystackIdx] < needle[needleIdx])
needleIdx--;
else
haystack.RemoveAt(haystackIdx--);
}