web-dev-qa-db-ja.com

思ったように機能しない以外はLinqを使用する

List1にはアイテム{ A, B }が含まれ、List2にはアイテム{ A, B, C }が含まれます。

Except Linq拡張機能を使用すると、{ C }が返されます。代わりに{ A, B }が返されます。式でリストを逆にすると、結果は{ A, B, C }になります。

Exceptのポイントを誤解していますか?使用していない別の拡張機能はありますか?

私はこの問題について多くの異なる記事をよく読んで試しましたが、これまでのところ成功していません。

var except = List1.Except(List2); //This is the line I have thus far

編集:はい私は単純なオブジェクトを比較していました。私はIEqualityComparerを使用したことがありません。学ぶのは面白かったです。

助けてくれてありがとう。問題はコンパレータを実装していませんでした。以下のリンクされたブログ投稿と例が参考になります。

16
Schanckopotamus

リストに参照型を格納する場合は、オブジェクトが等しいかどうかを比較する方法があることを確認する必要があります。それ以外の場合は、同じアドレスを参照しているかどうかを比較してチェックされます。

IEqualityComparer<T>を実装して、パラメーターとして Except() 関数に送信できます。こちらが ブログ投稿 です。

edit元のブログ投稿リンク =壊れていて、上で置き換えられました

17

だから完全のために...

// Except gives you the items in the first set but not the second
    var InList1ButNotList2 = List1.Except(List2);
    var InList2ButNotList1 = List2.Except(List1);
// Intersect gives you the items that are common to both lists    
    var InBothLists = List1.Intersect(List2);

編集:リストにはオブジェクトが含まれているため、クラスのIEqualityComparerに渡す必要があります...作成したオブジェクトに基づくサンプルIEqualityComparerを使用した場合の例外は次のとおりです...:)

// Except gives you the items in the first set but not the second
        var equalityComparer = new MyClassEqualityComparer();
        var InList1ButNotList2 = List1.Except(List2, equalityComparer);
        var InList2ButNotList1 = List2.Except(List1, equalityComparer);
// Intersect gives you the items that are common to both lists    
        var InBothLists = List1.Intersect(List2);

public class MyClass
{
    public int i;
    public int j;
}

class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass x, MyClass y)
    {
        return x.i == y.i &&
               x.j == y.j;
    }

    public int GetHashCode(MyClass obj)
    {
        unchecked
        {
            if (obj == null)
                return 0;
            int hashCode = obj.i.GetHashCode();
            hashCode = (hashCode * 397) ^ obj.i.GetHashCode();
            return hashCode;
        }
    }
}
7
Kevin

単に引数の順序を混乱させただけです。 公式ドキュメント は次のように役に立たないため、この混乱がどこで発生したかを確認できます。

デフォルトの等値比較子を使用して値を比較することにより、2つのシーケンスの差集合を生成します。

セット理論に精通していなければ、実際には セットの違い が何であるか明確ではないかもしれません。それは、セット間の違いだけではありません。実際には、Exceptは、2番目のセットにない最初のセットの要素のリストを返します。

これを試して:

var except = List2.Except(List1); // { C }
7
p.s.w.g