2

私はすべての写真を保存するMongoDBデータベースを持っており、それらを取得するときにいくつかのdoubleを保存しましたが、これはあまり良くありませんが、とにかく個別の要素のみを表示したいと思います。

 @foreach (Foto f in fotos.Distinct(new IEqualityComparer<Foto> { )

しかし、Fotoクラスにはsmallurlという1つのプロパティがあり、このプロパティによって個別の要素のみを表示したいと思います。したがって、カスタムIEqualityComparerを作成する方法。

4

6 に答える 6

2
var listOfUrls = fotos.Select(f => f.smallurl).Distinct();

あなたの質問に具体的に答えるために編集する

c#IEqualityComparerhttp : //msdn.microsoft.com/en-us/library/ms132151.aspxの検索で見つけることができるMSDNドキュメントから実際にコピーされます

class FotoEqualityComparer : IEqualityComparer<Foto>
{
    public bool Equals(Foto f1, Foto f2)
    {
        return f1.smallurl == f2.smallurl;
    }
    public int GetHashCode(Foto f)
    {
         return f.smallurl.GetHashCode();
    }
}

@foreach (Foto f in fotos.Distinct(new FotoEqualityComparer() )
于 2012-10-25T18:16:51.310 に答える
2

実はとても簡単です。次のように、メソッドに識別性セレクターを提供するだけです。

    public static IEnumerable<TSource> DistinctBy<TSource, TResult>(this IEnumerable<TSource> enumerable, Func<TSource, TResult> keySelector)
    {
        Dictionary<TResult, TSource> seenItems = new Dictionary<TResult, TSource>();

        foreach (var item in enumerable)
        {
            var key = keySelector(item);

            if (!seenItems.ContainsKey(key))
            {
                seenItems.Add(key, item);
                yield return item;
            }
        }
    }

または、別の実装を作成して、IEquality比較子の汎用実装を作成することもできます。

    public static IEnumerable<TSource> DistinctBy<TSource>(this IEnumerable<TSource> enumerable, Func<TSource, TSource, bool> equalitySelector, Func<TSource, int> hashCodeSelector)
    {
        return enumerable.Distinct(new GenericEqualitySelector<TSource>(equalitySelector, hashCodeSelector));
    }

    class GenericEqualitySelector<TSource> : IEqualityComparer<TSource>
    {
        public Func<TSource, TSource, bool> _equalityComparer = null;
        public Func<TSource, int> _hashSelector = null;

        public GenericEqualitySelector(Func<TSource, TSource, bool> selector, Func<TSource, int> hashSelector)
        {
            _equalityComparer = selector;
            _hashSelector = hashSelector;
        }

        public bool Equals(TSource x, TSource y)
        {
            return _equalityComparer(x, y);
        }

        public int GetHashCode(TSource obj)
        {
            return _hashSelector(obj);
        }
    }
于 2012-10-25T18:17:22.513 に答える
1

MSDNから変更

public class MyEqualityComparer : IEqualityComparer<Foto>
{
    public bool Equals(Foto x, Foto 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 foto's properties are equal. 
        return x.smallurl == y.smallurl ;
    }

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

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

        //Get hash code for the foto.smallurl field if it is not null. 
        return foto.smallurl == null ? 0 : foto.smallurl.GetHashCode();
    }
}
于 2012-10-25T18:19:24.090 に答える
1

自分で作る:

public class FotoEqualityComparer : IEqualityComparer<Foto>
{
    public bool Equals(Foto x, Foto y)
    {
         return x.smallurl.Equals(y.smallurl);   
    }

    public int GetHashCode(Foto foto)
    {
         return foto.smallurl.GetHashCode();
    }
}

そしてそれを次のように使用します:

fotos.Distinct(new FotoEqualityComparer());

編集:

.Distinct()のインラインラムダオーバーロードはありません。2つのオブジェクトが等しく比較される場合、それらは同じGetHashCode戻り値を持っている必要があるためです(そうでない場合、Distinctによって内部的に使用されるハッシュテーブルは正しく機能しません)。

ただし、1行にしたい場合は、グループ化して同じ結果を得ることができます。

fotos.GroupBy(f => f.smallurl).Select(g => g.First());
于 2012-10-25T18:35:13.323 に答える
1

代わりにGroupByを使用したはるかに単純なコード:

@foreach (Foto f in fotos.GroupBy(f => f.smallurl).Select(g => g.First()))
于 2012-10-25T19:08:57.657 に答える
0

独自のEqulityComparerを作成する必要があります。

    class FotoEqualityComparer : IEqualityComparer<Foto>
    {

    public bool Equals(Foto b1, Foto b2)
    {
            if (b1.smallurl == b2.smallurl)                
                return true;                
            else        
                return false;        
    }


    public int GetHashCode(Foto bx)
    {
            int hCode = bx.smallurl ;
            return hCode.GetHashCode();
    }

    }
于 2012-10-25T18:21:39.643 に答える