是否可以使用比较器从列表中删除项目?

时间:2012-12-03 10:15:17

标签: c#

我有一个像这样的POCO:

class Poco{
    int first;
    int last;
    int category;
}

和一个清单

List<Poco> pocoList;

我需要从列表中删除与具有指定类别的项目重叠的项目,重叠定义为:

if (a.category!=category && (a.first >= b.first && a.first <= b.last) || (a.last >= b.first && a.last <= b.last)){
  // delete item a 
}

两个重叠的项目永远不会有相同的类别。最后总是大于第一。第一个和最后一个定义范围。可能存在多个重叠。

列表的排序使得List [n] .start&lt;列表[n + 1] .start始终为真。

例如,如果类别为10,我需要删除所有没有10类别的项目,并且该项目范围的任何部分与类别为10的项目范围重叠。

我当前的实现是粗略的,在分析我的应用程序时,我可以看到处理分支的整个时间的65%用于此循环,这并不奇怪。

for (int i=object.pojoList.Count-1;i>=0;i--){
    for (int j=object.pocoList.Count-1;j>=0;j--){
        if (pocoList[i].overlaps(pocoList[j],category){
            pocoList.RemoveAt(j);
        }            
    }
}

我觉得必须有一种方法可以使用比较器或LINQ删除项目,但我无法弄明白。

有什么建议吗?谢谢。

2 个答案:

答案 0 :(得分:1)

由于您的输入列表是start顺序,您可以尝试类似

的内容
List<Poco> potentialOverlaps = new List<Poco>();
for (int i = 0; i < pocoList.Count; i++)
{
    var currentPoco = pocoList[i];

    // Clear out overlaps that end before this poco starts.
    potentialOverlaps.RemoveAll(p => p.last < currentPoco.first);

    if (currentPoco.category == category)
    {
        potentialOverlaps.Add(currentPoco);
    }
    else if (potentialOverlapsCount > 0)
    {
        pocoList.RemoveAt(i);
        i--;
    }
}

结果可能与您的代码所给出的结果不同,但它应符合您描述的行为。

它会跟踪您所选类别中“尚未结束”的Poco;如果遇到类别Poco并且有任何“尚未结束”,则必须与其中一个重叠,以便删除。

答案 1 :(得分:0)

您可以让您的类实现IComparer。

你必须以一种方式实现方法Compare(Object,Object),它返回1,0或-1分别为更大,相等或更小。

良好情况的来源:link

您可以在一个列表中设置另一个列表的分隔符。然后,当使用上述方法进行排序时,如果该值与分隔符的范围重叠,则将其删除。