2

2つの一般的なリストがある場合。LINQを使用して他のリストにないものを見つけるにはどうすればよいですか?

これが私のobjクラスです:

 public class tobj
 {      
    public string column1;
    public string column2;
 }  

これが配列です

 tobj[] array1 = 
 { 
        new tobj { "1", "1" }, new tobj { "2", "2" }, new tobj { "3", "3" } 
 };

 tobj[] array2 = 
 { 
     new tobj { "2", "2" }, new tobj { "3", "3" }, new tobj { "4", "4" } 
 };

 var diff = array1.FinfDiff(array2); 

 foreach (var value in diff)
 {
    Console.WriteLine(value.column1); // 1
 }

このコードはまだテストされていません。

4

3 に答える 3

4

使用できますExcept。ただし、カスタム タイプがある場合は、Linq で適切に機能するよう にオーバーライドする必要がEquals()あります。GetHashCode()

これは、Linq が効率を追求しているためです。そのためHashSet<T>、他のメカニズムを使用して、アイテムが同等かどうかをすばやく判断できます (同等のアイテムには同じハッシュ コードが必要であるか、ハッシュ コードが正しくない)。したがって、 を実装するだけでは十分ではなく、カスタム クラスでこのタイプのメソッドを使用する場合にEquals()も実装する必要があります。GetHashCode()

例えば:

    public class tobj : IEquatable<tobj>
    {
        public string column1;
        public string column2;

        public bool Equals(tobj other)
        {
            return other != null ? Equals(column1, other.column1) && Equals(column2, other.column2) : false;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as tobj);
        }

        public override int GetHashCode()
        {
            // seed the code
            int hash = 13;

            // use some primes to mix in the field hash codes...
            hash = hash * 17 + column1.GetHashCode();
            hash = hash * 17 + column2.GetHashCode();

            return hash
        }
    }  

GetHashCode() と Equals() をオーバーライドしたので (私IEquatable<T>自身も実装するのが好きです)、以下を使用できますExcept()

        var results = array1.Except(array2);

        foreach (var i in results)
        {
            Console.WriteLine(i.column1 + ":" + i.column2);
        }

良いものを実装するためのヒントについては、ハッシュコードのアルゴリズムに関するこの SO スレッドを参照することをお勧めします。

また、補足として、一部の型 ( KeyValuePairTuple、および匿名型など)は、個々のコンポーネントを考慮に入れる方法で等価性を既に実装Equals()し、正しく実装しています。GetHashCode()

于 2012-05-18T20:25:45.807 に答える
2

IEnumerable で利用できる Except メソッドを使用できます。実装は簡単です。ここで概説されている例を見ることができます: http://msdn.microsoft.com/en-us/library/bb336390.aspx

于 2012-05-18T20:17:45.220 に答える
0
array2.ForEach(x => array1.Remove(x));

array1 に残っているのはあなたの結果です

編集: アイテムは「単純な」オブジェクトではないことを一目見ません... Jamesが書いているように、equalをオーバーライドする必要があります

于 2012-05-18T20:27:46.877 に答える