2015-07-13 74 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。但是,它有關係嗎?