分别收集2个不同的新系列

时间:2016-08-26 11:07:04

标签: c# linq collections

我有一些元素和一个额外的小集合作为过滤器。

我需要通过一些过滤器将它分成两个新的集合。在我的例子中,它是第一个包含一些元素的集合,而另一个则不包含。

这2个新集合中没有不存在的项目。

我这样做了:

var collection1= baseCollection.Where(r => filterCollection.Contains(r.Property)).ToList();
var collection2= baseCollection.Where(r => !filterCollection.Contains(r.Property)).ToList();

但还有另一种,我希望更优雅的方式,分开收藏? 对我来说,它看起来像“我重复自己”,使用几乎相同的代码2次。

1 个答案:

答案 0 :(得分:8)

  1. 您可以为该功能创建一个变量 - 这样您就不会重复自己" (在这种情况下不会使用,下面有更好的选项,但仍然是一个选项)

    Func<YourClass,bool> filtering = (r) => filterCollection.Contains(r.Property);
    
    var collection1 = baseCollection.Where(r => filtering(r));
    var collection2 = baseCollection.Where(r => !filtering(r));
    
  2. 如果您的收藏类型会覆盖EqualsGetHashCode,则可以使用Except

    var collection1 = baseCollection.Where(r => filterCollection.Contains(r.Property));
    var collection2 = baseCollection.Except(collection1);
    
  3. 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());
    
  4. 您还可以使用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];
    
  5. 否则另一种方法就是使用循环:

    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);
        }
    }