从有序集合中删除项目的最佳方法是什么?

时间:2010-12-16 22:15:36

标签: c# collections html-lists

我有一个要从C#中的有序集合中删除的项目列表。

最好的方法是什么?

如果我删除了中间的项目,索引会更改,但如果我想删除多个项目,该怎么办?

4 个答案:

答案 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);
}

这样,只有haystackneedle的遍历,加上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--);
}