-1

重複したアイテムを削除するためにlinqを試しました:

   var MyItems = (from b in this.result
               select new Item{ Name = b.Name, ID = b.ID }).Distinct();

結果を確認したところ、重複した項目が削除されていません。この問題を解決するにはどうすればよいですか?

4

7 に答える 7

5

デフォルトでDistinct()EqualityComparer<T>.Default、を使用します。これには次のルールがあります。

デフォルトの等式比較機能であるDefaultは、IEquatableジェネリックインターフェイスを実装するタイプの値を比較するために使用されます。カスタムデータ型を比較す​​るには、このインターフェイスを実装し、その型に独自のGetHashCodeメソッドとEqualsメソッドを提供する必要があります。

あなたの場合、これはItemを実装する必要があることを意味しますIEquatable<Item>

または、オーバーロードをDistinct直接IEqualityComparer<T>使用することもできます。

于 2012-06-29T15:49:00.820 に答える
3

Distinct() に比較オブジェクトを渡すことができます。

var MyItems = (from b in this.result
           select new Item{ Name = b.Name, ID = b.ID }).Distinct(new ItemComparer());

カスタム比較クラスの例を次に示します。

// Custom comparer for the Item class
class ItemComparer: IEqualityComparer<Product>
{
    // Items are equal if their names and IDs are equal.
    public bool Equals(Item x, Item y)
    {

        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

    //Check whether the items' properties are equal.
    return x.ID == y.ID && x.Name == y.Name;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Item item)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(item, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashItemName = item.Name == null ? 0 : item.Name.GetHashCode();

        //Get hash code for the ID field.
        int hashItemID = item.ID.GetHashCode();

        //Calculate the hash code for the item.
        return hashItemName ^ hashItemID;
    }

}
于 2012-06-29T15:55:06.837 に答える
1

プリミティブではなくオブジェクトを比較しているので、Distinct意味を定義するためにいくつかの作業を行う必要があります。

Distinct以下を含むオーバーライドを見てください:http IEqualityComparer//msdn.microsoft.com/en-us/library/bb338049.aspx

于 2012-06-29T15:48:58.463 に答える
1

通常Distinct()は、既定の等値比較子を使用してコレクションから要素を返します。

これにはカスタム比較子を使用できます。

// modified example from docs, not tested
class MyComparer : IEqualityComparer<Item>
{
    // Items are equal if their ids are equal.
    public bool Equals(Item x, Item y)
    {

        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the items properties are equal.
        return x.ID == y.ID;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(item, null)) return 0;

        //Get hash code for the ID field.
        int hashProductId = product.ID.GetHashCode();

        return hashProductId;
    }

}

var myItems = (from b in this.result
               select new Item{ Name = b.Name, ID = b.ID }).Distinct(new MyComparer());
于 2012-06-29T15:46:22.957 に答える
1

この後どう使うか分からないのでItems、ここでギャンブルです。

本当に ID と名前のペアだけが必要な場合は、匿名型を使用して無料で比較を取得できます。

var MyItems = (from b in this.result
               select new { b.Name, b.ID }).Distinct();

この後 (また、必要なのは名前と ID のペアだけであると仮定します)、結果のオブジェクトには必要なプロパティが含まれます。

foreach(var item in MyItems)
    Console.WriteLine("{0} -> {1}", item.ID, item.Name);

C# 匿名型に関する MSDN の引用:

匿名型の Equals および GetHashCode メソッドは、プロパティの Equals および GetHashcode メソッドに関して定義されるため、同じ匿名型の 2 つのインスタンスが等しいのは、それらのすべてのプロパティが等しい場合のみです。

于 2012-06-29T15:53:49.243 に答える
-4

リストに新しい項目を追加する必要があります。foreach 試験を使用します。

foreach(var _item in result.Distinct()){
//Code here
}

わかった :)

于 2012-06-29T15:57:51.797 に答える