我有一些元素和一个额外的小集合作为过滤器。
我需要通过一些过滤器将它分成两个新的集合。在我的例子中,它是第一个包含一些元素的集合,而另一个则不包含。
这2个新集合中没有不存在的项目。
我这样做了:
var collection1= baseCollection.Where(r => filterCollection.Contains(r.Property)).ToList();
var collection2= baseCollection.Where(r => !filterCollection.Contains(r.Property)).ToList();
但还有另一种,我希望更优雅的方式,分开收藏? 对我来说,它看起来像“我重复自己”,使用几乎相同的代码2次。
答案 0 :(得分:8)
您可以为该功能创建一个变量 - 这样您就不会重复自己" (在这种情况下不会使用,下面有更好的选项,但仍然是一个选项):
Func<YourClass,bool> filtering = (r) => filterCollection.Contains(r.Property);
var collection1 = baseCollection.Where(r => filtering(r));
var collection2 = baseCollection.Where(r => !filtering(r));
如果您的收藏类型会覆盖Equals
和GetHashCode
,则可以使用Except
:
var collection1 = baseCollection.Where(r => filterCollection.Contains(r.Property));
var collection2 = baseCollection.Except(collection1);
将Except
与给定IEqualityComparer
一起使用(同时检查guidlines的第一条评论):
public class Comparer : IEqualityComparer<YourClass>
{
public bool Equals(YourClass x, YourClass y)
{
// Your implementation
}
public int GetHashCode(YourClass obj)
{
// Your implementation
}
}
var collection1 = baseCollection.Where(r => filterCollection.Contains(r.Property));
var collection2 = baseCollection.Except(collection1, new Comparer());
您还可以使用GroupBy
(可能效果不佳):
var result baseCollection.GroupBy(r => filterCollection.Contains(r.Property))
.ToDictionary(key => key.Key, value => value.ToList());
var collection1 = result[true];
var collection2 = result[false];
否则另一种方法就是使用循环:
List<YourType> collection1 = new List<YourType>();
List<YourType> collection2 = new List<YourType>();
foreach(var item in baseCollection)
{
if(filterCollection.Contains(item.Property))
{
collection1.Add(item);
}
else
{
collection2.Add(item);
}
}