如何从IEnumerable中删除符合特定条件的项目?
RemoveAll()不适用。
你不能;IEnumerable
作为一个接口不支持移除操作。
如果你的 IEnumerable
实例实际上是一个支持移除操作的类型(例如 List<T>
),那么你可以将其强制转换为该类型,并使用 Remove
方法。
或者,你可以根据自己的条件将项目复制到另一个基于 IEnumerable
的集合中,也可以使用延迟评估查询(例如 Linq 的 .Where
)动态筛选你的 IEnumerable
。但这两种方法都不会影响你的原始容器。
IEnumerable
上执行.Aggregate
。我按照丹的建议插入了一个.Where
过滤器,例如foo.Where(condition).Aggregate(expression)
。它非常顺利地工作了。 - Codes with Hammer var filtered = myCollection.Where(x => x.SomeProp != SomValue);
另一个选择是使用Where
创建一个新的IEnumerable<T>
,其中包含对要删除的对象的引用,然后将其传递给原始集合上的Remove
调用。当然,这实际上会消耗更多的资源。
Where
将会产生一个新的集合。LINQ 查询通常不会修改现有的集合,而是生成一个带有结果集的新的 IEnumerable<T>
。 - evanmcdonnal正如大家已经说过的那样,您不能从IEnumerable中删除元素,因为这不是该接口所描述的。考虑以下示例:
public IEnumerable<string> GetSomeStrings()
{
yield return "FirstString";
yield return "Another string";
}
显然,从这个 IEnumerable
中删除一个元素并不是你可以合理地做的事情,相反,你需要创建一个新的枚举,不包含你不想要的元素。
yield
关键字提供了其他示例,例如,你可以拥有无限列表:
public IEnumberable<int> GetPowersOf2()
{
int value = 1;
while(true)
{
yield return value;
value = value * 2;
}
}
IEnumerable<T>
中移除项目。你可以从 ICollection<T>
中移除项,或者从 IEnumerable<T>
中过滤项目。// filtering example; does not modify oldEnumerable itself
var filteredEnumerable = oldEnumerable.Where(...);
// removing example
var coll = (ICollection<MyClass>)oldEnumerable;
coll.Remove(item);
IEnumerable
的基础数据源。但这仍然不是从IEnumerable
中删除项,而是从基础数据源中删除项。 - Servy这是我的做法,
IEnumerable<T> myVar=getSomeData(); // Assume mayVar holds some data
myVar=myVar.Where(d=>d.Id>10); // thats all, i want data with Id>10 only
List<T>.RemoveAll(Predicate<T> match)
,这正是你所需要的。尝试使用Enumerable.Empty
怎么样?
T obj = new T();
IEnumerable<T> myVar = new T[]{obj} //Now myVar has an element
myVar = Enumerable.Empty<T>(); //Now myVar is empty