【问题标题】:Uniquifying a list (C#)使列表唯一化 (C#)
【发布时间】:2016-05-20 10:36:35
【问题描述】:

我正在尝试使用自定义相等比较器从列表中删除重复项,但我似乎无法正确处理。

简化示例:

class A
{
    public A(string Test) { this.Test = Test; }
    public string Test;
    public string ToString() { return Test; }
}

class AsComparer: EqualityComparer<A>
{
    public override bool Equals(A x, A y)
    {
        return (x.Test == y.Test);
    }

    public override int GetHashCode(A obj)
    {
        return obj.Test.GetHashCode();
    }
}

static private void Test()
{
    var As = new List<A> { new A("Test1"), new A("Test3"), new A("Test1"), new A("Test2") };
    As.Distinct(new AsComparer());
    As.Sort((e1, e2) => { return (e1.Test.CompareTo(e2.Test)); });
}

这将返回集合“Test1”、“Test1”、“Test2”、“Test3”。我希望只有一个“Test1”,但似乎无法弄清楚如何正确地做到这一点。

有什么想法吗?

【问题讨论】:

    标签: c# linq list distinct


    【解决方案1】:

    Distinct 返回一个IEnumerable&lt;T&gt;,它不对源列表本身进行操作。你必须这样做:

    As = As.Distinct(new AsComparer()).ToList()
    

    您还可以在此处包含您的排序:

    As = As
        .Distinct(new AsComparer())
        .OrderBy(x => x.Test)
        .ToList()
    

    【讨论】:

      【解决方案2】:

      Distinct() 返回一个全新的IEnumerable,所以:

      var result = 
        As.
          Distinct(new AsComparer()).
          OrderBy(e => e.Test).
          ToList();
      

      【讨论】:

      • 很确定SortList&lt;T&gt; 的方法,因此不能在IEnumerable&lt;T&gt; 上调用。同样Sort 返回 void: msdn.microsoft.com/en-us/library/b0zbh7b6(v=vs.110).aspx - Linq 等价物将是 OrderBy: As.Distinct(new AsComparer()).OrderBy(x =&gt; x.Test).ToList()
      • @HenrikIlgen 我在想什么?谢谢,已修复!
      【解决方案3】:

      我认为在你的课堂上使用 IEquatable 会更好

      class A : IEquatable<A>
      {
          public A(string Test) { this.Test = Test; }
          public string Test;
          public bool Equals(A other)
          {
              return Equals(Test, other.Test);
          }
      
          public override bool Equals(object obj)
          {
              if (ReferenceEquals(null, obj)) return false;
              if (ReferenceEquals(this, obj)) return true;
              if (obj.GetType() != GetType()) return false;
              return Equals((A)obj);
          }
      
          public override int GetHashCode()
          {
              unchecked
              {
                  unchecked
                  {
                      return Test.GetHashCode();
                  }
              }
          }
      
          public string ToString() { return Test; }
      }
      

      那你就可以了

      var result = As.Distinct().OrderBy(x => x.Test).ToList();
      

      【讨论】:

      • 这在很大程度上取决于两个As 在Test 属性相同时是否总是被认为相等(在这种情况下你是绝对正确的)或者如果两个 As 与 Test 相等仅在某些情况下被视为相等(在这种情况下,最好只使用适当的 EqualityComparer)。
      • @HenrikIlgen 你是对的。我根据问题中提供的示例类发布了代码。
      猜你喜欢
      • 2012-01-15
      • 2016-10-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多