在列表中查找重复项并根据其他字段排除项目

时间:2017-10-12 09:20:16

标签: c# linq

我有一个包含2个字段的C#列表。我需要根据Field1找到重复项,但排除那些重复项,其中Field2对于给定的重复项对也是相同的。换句话说:

Field1  Field2  
-------------
0       0  
0       1  

应该在结果中,而

Field1  Field2  
-------------
0       1  
0       1  

不应该在结果中 到目前为止我得到了这个:

dups = myList
  .AsParallel()
  .GroupBy(x => x.field1)
  .Where(x => x.Count() > 1)
  .Select(x => x.Key);  

但我不知道如何根据Field2排除。

3 个答案:

答案 0 :(得分:1)

I would go for creating a custom IEqualityComparer :

class MyClass {
    public int field1;
    public int field2;
}

class MyClassComparer: EqualityComparer<MyClass>
{
    public override bool Equals(MyClass x, MyClass y)
    {
        if (x == null && y == null)
            return true;
        else if (x == null || x == null)
            return false;

        if (x.field1 == y.field1 && x.field2 == y.field2)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public override int GetHashCode(MyClass x)
    {
        int hCode = x.field1.GetHashCode() ^ x.field2.GetHashCode();
        return hCode.GetHashCode();
    }
}

Then you can just add a

.Distinct(new MyClassComparer())

to the result list. somehting like (maybe need some adaptation, can't test it right now) :

dups = myList
  .AsParallel()
  .GroupBy(x => x.field1)
  .Where(x => x.Count() > 1)
  .Select(x => x.Key)
  .ToList();

undupeds = 
  dups.Distinct(new MyClassComparer());

caveat: This does get rid of duplicates after the db query.

答案 1 :(得分:0)

Not much efficient, but does the job (if I understood the problem right):

myList.GroupBy(x=>x.field1)
      .Where(g=>g.Count()>1)
      .SelectMany(g=>g)
      .GroupBy(x=>new{x.field1,x.field2})
      .Where(g=>g.Count()==1)
      .SelectMany(g=>g);

For a sample of some tuples below:

var myList = new List<Tuple<int,int>>{
    new Tuple<int,int>(1,2),
    new Tuple<int,int>(1,2),
    new Tuple<int,int>(1,3),
    new Tuple<int,int>(1,4),
    new Tuple<int,int>(2,3),
    new Tuple<int,int>(2,4),
};

this returns (ran on linqpad):

enter image description here

答案 2 :(得分:0)

    List<Fields> RemoveDuplicates(List<Fields> fields)
    {
        List<Fields> removedDuplicates = new List<Fields>();

        fields.ForEach(f =>
        {
            if (removedDuplicates.FindAll(d => 
                d.Field1 == f.Field1 && 
                d.Field2 == f.Field2).Count == 0)
            {
                removedDuplicates.Add(f);
            }
        });

        return removedDuplicates;
    }

不确定这是否正是您所要求的,但它应该创建一个新列表,其中只有一个“Fields”对象的实例,用于原始列表中的每个副本。