2015-07-13 35 views
-3

我有自定义类型的两个列表对象Linq的语法来比较两个列表

List<Obj> list1; 
List<Obj> list2; 

class Obj 
{ 
    public List<X> xlist; 
    public List<Y> Ylist; 
    public bool mybool; 

} 

class X 
{ 
    int x; 
    float y; 

} 


class Y 
{ 
    sting str; 
    bool y; 

} 

我想比较,在列表1和List2每个成员都有平等的values.Is有可能做到这一点在LINQ。

+1

你想知道'list1'中的所有'xlist'项是否等于'list2'中的所有'xlist'项和'Ylist'中的相同吗?或者你也想要主持'Obj'本身。但是,订单是否重要? –

+2

只是我的看法,但不要如此痴迷LINQ。 LINQ存在为您节省时间。如果您花时间了解如何编写LINQ查询的时间比编写等效循环所用的时间要长,那么您应该只编写循环。 – Taekahn

回答

1

您必须重写EqualsGetHashCode有意义。您也可以实现IEquatable<Obj>或使用LINQ方法(如SequenceEqualExcept)的自定义IEqualityComparer<Obj>。例如:

public class Obj: IEquatable<Obj> 
{ 
    public List<X> xlist; 
    public List<Y> Ylist; 
    public bool mybool; 


    public bool Equals(Obj other) 
    { 
     if (other == null) return false; 
     if(object.ReferenceEquals(this, other)) return true; 
     if (mybool != other.mybool) return false; 
     return xlist.SequenceEqual(other.xlist) && Ylist.SequenceEqual(other.Ylist); 
    } 

    public override bool Equals(object obj) 
    { 
     return base.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int hash = mybool ? 13 : 19; 
      foreach (X x in xlist) 
      { 
       hash = hash * 31 + x.GetHashCode(); 
      } 
      foreach (Y y in Ylist) 
      { 
       hash = hash * 31 + y.GetHashCode(); 
      } 
      return hash; 
     } 
    } 
} 

public class X: IEquatable<X> 
{ 
    public int x; 
    public float y; 

    public bool Equals(X other) 
    { 
     if (other == null) return false; 
     if (object.ReferenceEquals(this, other)) return true; 
     return x == other.x && y == other.y; 

    } 

    public override bool Equals(object obj) 
    { 
     var other = obj as X; 
     if (other == null) return false; 
     return this.Equals(other); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int hash = 19; 
      hash = hash * 31 + x; 
      hash = hash * 31 + (int)y; 
      return hash; 
     } 
    } 
} 


public class Y : IEquatable<Y> 
{ 
    public string str; 
    public bool y; 

    public bool Equals(Y other) 
    { 
     if (other == null) return false; 
     if (object.ReferenceEquals(this, other)) return true; 
     return str == other.str && y == other.y; 

    } 

    public override bool Equals(object obj) 
    { 
     var other = obj as Y; 
     if (other == null) return false; 
     return this.Equals(other); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int hash = 19; 
      hash = hash * 31 + (str == null ? 0 : str.GetHashCode()); 
      hash = hash * 31 + (y ? 1 : 0); 
      return hash; 
     } 
    } 
} 

现在你可以使用SequenceEqualList<Obj>

bool sameItemsSameOrder = list1.SequenceEqual(list2); // finally you got your one-liner 
0

有扩展方法SequenceEqual。 “通过使用默认相等比较器的类型比较元素,确定两个序列是否相等。”与你自己的相等比较器重载。

var areEqual = list1.SequenceEqual(list2); 

默认情况下,它调用列表中的对象的Equals方法,所以一定要确保它你需要什么,或者通过自己的相等比较。

Linq是一种查询语法。你需要Linq来例如在一个列表中查找不在另一个列表中的项目。比较序列与SequenceEqual不是一个查询,恕我直言,不是真正的Linq。但是,它有关系吗?