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

dem*_*emo 3 c# linq collections

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

我需要通过一些过滤器将它分成两个新的集合.在我的情况下,它是第一个包含一些元素的集合,另一个不包含.

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

我这样做了:

var collection1= baseCollection.Where(r => filterCollection.Contains(r.Property)).ToList();
var collection2= baseCollection.Where(r => !filterCollection.Contains(r.Property)).ToList();
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*een 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));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您的集合类型覆盖Equals,GetHashCode您可以使用Except:

    var collection1 = baseCollection.Where(r => filterCollection.Contains(r.Property));
    var collection2 = baseCollection.Except(collection1);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用Except给定(也检查guidlines的第一个评论):IEqualityComparer

    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());
    
    Run Code Online (Sandbox Code Playgroud)
  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];
    
    Run Code Online (Sandbox Code Playgroud)
  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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • ``除了`比'Where'更快,因为它使用基于集合的方法来过滤.你可以使用[overload](https://msdn.microsoft.com/en-us/library/bb336390(v = vs.110).aspx)而不是覆盖`Equals` +`GetHashCode`.的IEqualityComparer <T>`. (2认同)