简体   繁体   English

从IList中删除N个匹配谓词的项目

[英]Remove N items from IList where match predicate

I would like to remove N items from an IList collection. 我想从IList集合中删除N个项目。 Here's what I've got: 这是我得到的:

public void RemoveSubcomponentsByTemplate(int templateID, int countToRemove)
{
    //  TaskDeviceSubcomponents is an IList
    var subcomponents = TaskDeviceSubcomponents.Where(tds => tds.TemplateID == templateID).ToList();

    if (subcomponents.Count < countToRemove)
    {
        string message = string.Format("Attempted to remove more subcomponents than found. Found: {0}, attempted: {1}", subcomponents.Count, countToRemove);
        throw new ApplicationException(message);
    }

    subcomponents.RemoveRange(0, countToRemove);
}

Unfortunately, this code does not work as advertised. 不幸的是,此代码无法像宣传的那样工作。 TaskDeviceSubcomponents is an IList, so it doesn't have the RemoveRange method. TaskDeviceSubcomponents是一个IList,因此它没有RemoveRange方法。 So, I call .ToList() to instantiate an actual List, but this gives me a duplicate collection with references to the same collection items. 因此,我调用.ToList()实例化一个实际的List,但这给了我一个重复的集合,其中引用了相同的集合项。 This is no good because calling RemoveRange on subcomponents does not affect TaskDeviceSubcomponents. 这不好,因为在子组件上调用RemoveRange不会影响TaskDeviceSubcomponents。

Is there a simple way to achieve this? 有没有简单的方法可以做到这一点? I'm just not seeing it. 我只是没有看到它。

Unfortunately, I think you need to remove each item individually. 不幸的是,我认为您需要单独删除每个项目。 I would change your code to this: 我将您的代码更改为此:

public void RemoveSubcomponentsByTemplate(int templateID, int countToRemove)
{
    //  TaskDeviceSubcomponents is an IList
    var subcomponents = TaskDeviceSubcomponents
                         .Where(tds => tds.TemplateID == templateID)
                         .Take(countToRemove)
                         .ToList();

    foreach (var item in subcomponents)
    {
        TaskDeviceSubcomponents.Remove(item);
    }
}

Note that it is important to use ToList here so you are not iterating TaskDeviceSubcomponents while removing some of its items. 请注意,在此处使用ToList很重要,因此在删除TaskDeviceSubcomponents某些项目时不会对其进行迭代。 This is because LINQ uses lazy evaluation, so it doesn't iterate over TaskDeviceSubcomponents until you iterate over subcomponents . 这是因为LINQ使用懒惰的评价,所以它不会遍历TaskDeviceSubcomponents直到你迭代subcomponents

Edit: I neglected to only remove the number of items contained in countToRemove , so I added a Take call after the Where . 编辑:我忽略了仅删除countToRemove包含的项目数,因此我在Where之后添加了Take调用。

Edit 2: Specification for the Take()-Method: http://msdn.microsoft.com/en-us/library/bb503062(v=vs.110).aspx 编辑2: Take()方法的规范: http : //msdn.microsoft.com/zh-cn/library/bb503062 (v= vs.110 ) .aspx

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

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