繁体   English   中英

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

[英]What's the best way to remove items from an ordered collection?

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

最好的方法是什么?

如果我在中间删除一个项目,索引会改变,但是如果我想删除多个项目该怎么办?

为了避免索引更改,请从末尾开始,然后返回索引0。

遵循以下原则:

for(int i = myList.Count - 1; i >= 0; i++) 
{
    if(NeedToDelete(myList[i]))
    {
        myList.RemoveAt(i);
    }
}

收藏的类型是什么? 如果它继承自ICollection ,则可以对要删除的项目列表进行循环,然后在集合上调用.Remove()方法。

例如:

object[] itemsToDelete = GetObjectsToDeleteFromSomewhere();
ICollection<object> orderedCollection = GetCollectionFromSomewhere();

foreach (object item in itemsToDelete)
{
    orderedCollection.Remove(item);
}

如果集合是List<T> ,则还可以使用RemoveAll方法:

list.RemoveAll(x => otherlist.Contains(x));

假设要删除的项目列表相对较短,则可以首先对目标列表进行排序。 比遍历源列表并在目标列表中保留一个与您删除的项目相对应的索引。

假设源列表是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 1个遍历,再加上对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--);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM