लैम्ब्डा के साथ डिस्टिंक्ट ()?


746

सही है, इसलिए मेरे पास एक योग्य है और इससे अलग-अलग मूल्य प्राप्त करने की इच्छा है।

का उपयोग करते हुए System.Linq, निश्चित रूप से एक एक्सटेंशन विधि कहा जाता है Distinct। सरल मामले में, इसका उपयोग बिना मापदंडों के साथ किया जा सकता है, जैसे:

var distinctValues = myStringList.Distinct();

अच्छी तरह से और अच्छा है, लेकिन अगर मेरे पास ऐसी वस्तुओं का बोधगम्य है जिसके लिए मुझे समानता निर्दिष्ट करने की आवश्यकता है, तो केवल उपलब्ध अधिभार है:

var distinctValues = myCustomerList.Distinct(someEqualityComparer);

समानता तुष्टिकरण तर्क का एक उदाहरण होना चाहिए IEqualityComparer<T>। मैं यह कर सकता हूँ, बेशक, लेकिन यह कुछ हद तक क्रियात्मक है और, अच्छी तरह से, स्पष्ट है।

मुझे उम्मीद है कि एक अधिभार है जो एक मेमने को ले जाएगा, एक फंक <टी, टी, बूल> कहेंगे:

var distinctValues
    = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);

किसी को पता है कि क्या ऐसा कुछ विस्तार मौजूद है, या कुछ बराबर वर्कअराउंड? या क्या मैं कुछ न कुछ भूल रहा हूं?

वैकल्पिक रूप से, वहाँ एक IEqualityComparer इनलाइन (मुझे शर्मिंदा) निर्दिष्ट करने का एक तरीका है?

अपडेट करें

मुझे इस विषय पर एक MSDN फोरम में एक पोस्ट के लिए एंडर्स हेजेल्सबर्ग द्वारा एक उत्तर मिला । वह कहता है:

आप जिस समस्या को चलाने जा रहे हैं, वह यह है कि जब दो वस्तुएं समान तुलना करती हैं, तो उनके पास समान GetHashCode रिटर्न वैल्यू होनी चाहिए (या फिर डिस्टिंच द्वारा आंतरिक रूप से उपयोग की जाने वाली हैश तालिका सही ढंग से काम नहीं करेगी)। हम IEqualityComparer का उपयोग करते हैं क्योंकि यह समान इंटरफ़ेस और GetHashCode के संगत कार्यान्वयन को एक एकल इंटरफ़ेस में पैकेज करता है।

मुझे लगता है कि समझ में आता है ..


2
देख stackoverflow.com/questions/1183403/... एक समाधान GroupBy उपयोग करने के लिए

17
एंडर्स हेजलबर्ग अपडेट के लिए धन्यवाद!
Tor Haugen

नहीं, यह समझ में नहीं आता है - कैसे दो वस्तुओं में समान मूल्य वाले दो अलग-अलग हैश-कोड वापस आ सकते हैं ??
GY

यह मदद कर सकता है - समाधान के लिए .Distinct(new KeyEqualityComparer<Customer,string>(c1 => c1.CustomerId)), और इसका कारण बताएं GetHashCode () ठीक से काम करने के लिए महत्वपूर्ण है।
मारबेल 82

संबंधित / संभव डुप्लिकेट: LINQ's Distinct () एक विशेष संपत्ति पर
Marc.2377

जवाबों:


1028
IEnumerable<Customer> filteredList = originalList
  .GroupBy(customer => customer.CustomerId)
  .Select(group => group.First());

12
अति उत्कृष्ट! यह विस्तार विधि में वास्तव में आसान है, जैसे DistinctBy(या यहां तक ​​कि Distinct, क्योंकि हस्ताक्षर अद्वितीय होगा)।
टॉमस एशचन

1
मेरे लिए काम नहीं करता है! <विधि 'प्रथम' का उपयोग केवल अंतिम क्वेरी ऑपरेशन के रूप में किया जा सकता है। इस उदाहरण में 'FirstOrDefault' पद्धति का उपयोग करने पर विचार करें।> यहां तक ​​कि मैंने 'FirstOrDefault' का उपयोग करने की कोशिश की।
जाटसिंग

63
@TorHaugen: बस ध्यान रखें कि उन सभी समूहों को बनाने में एक लागत शामिल है। यह इनपुट को स्ट्रीम नहीं कर सकता है, और कुछ भी वापस करने से पहले सभी डेटा को बफर करेगा। यह आपकी स्थिति के लिए प्रासंगिक नहीं हो सकता है, लेकिन मैं डिस्टिंक्टी की शान पसंद करता हूं :)
जॉन स्कीट

2
@JonSkeet: यह VB.NET कोडर्स के लिए काफी अच्छा है जो केवल एक फीचर के लिए अतिरिक्त लाइब्रेरीज़ आयात नहीं करना चाहते हैं। ASync CTP के बिना, VB.NET yieldस्टेटमेंट का समर्थन नहीं करता है इसलिए स्ट्रीमिंग तकनीकी रूप से संभव नहीं है। यद्यपि आपके उत्तर के लिए धन्यवाद। C # में कोडिंग करते समय मैं इसका उपयोग करूँगा। ;-)
एलेक्स एस्सिल्फ़ी

2
@BenGripka: यह काफी समान नहीं है। यह आपको केवल ग्राहक आईडी देता है। मुझे पूरा ग्राहक चाहिए :)
ryanman

496

यह मुझे लगता है कि आप MoreLINQDistinctBy से चाहते हैं । आप तब लिख सकते हैं:

var distinctValues = myCustomerList.DistinctBy(c => c.CustomerId);

यहाँ का कट-डाउन संस्करण है DistinctBy(कोई शून्य जाँच नहीं है और अपनी खुद की प्रमुख तुलना करने का कोई विकल्प नहीं है):

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
     (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> knownKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

14
मुझे पता था कि सबसे अच्छा जवाब जॉन स्कीट द्वारा पोस्ट के शीर्षक को पढ़कर ही पोस्ट किया जाएगा। अगर इसके LINQ, स्कीट के आदमी के साथ कुछ भी करना है। भगवान के समान लिंच ज्ञान प्राप्त करने के लिए Read सी # इन डेप्थ ’पढ़ें।
3

2
बहुत बढ़िया जवाब!!! इसके अलावा, सभी VB_Complainers yield+ अतिरिक्त देयता के बारे में , foreach फिर से लिखा जा सकता हैreturn source.Where(element => knownKeys.Add(keySelector(element)));
डेनिस मोरोज़ोव

5
@ sudhAnsu63 यह LinqToSql (और अन्य linq प्रदाताओं) की एक सीमा है। LinqToX का आशय X के मूल संदर्भ में आपकी C # लैम्ब्डा अभिव्यक्ति का अनुवाद करना है। अर्थात्, LinqToSql आपके C # को SQL में रूपांतरित करता है और जहाँ संभव हो, उस कमांड को मूल रूप से निष्पादित करता है। इसका मतलब है कि कोई भी विधि जो C # में रहती है, उसे linqProvider के माध्यम से "पास" नहीं किया जा सकता है यदि इसे SQL में व्यक्त करने का कोई तरीका नहीं है (या जो भी linq प्रदाता आप उपयोग कर रहे हैं)। मैं मॉडल देखने के लिए डेटा ऑब्जेक्ट को परिवर्तित करने के लिए इसे विस्तार विधियों में देखता हूं। डिस्टिंक्टबी () से पहले टॉलिस्ट () को कॉल करके आप क्वेरी को "भौतिक" करके इसके चारों ओर काम कर सकते हैं।
माइकल ब्लैकबर्न

1
और जब भी मैं इस सवाल पर वापस आता हूं तो मैं सोचता रहता हूं कि वे BCL में कम से कम MoreLinq को क्यों नहीं अपनाते।
शिम्मी वीट्ज़ंडलर

2
@ शमी: मैं निश्चित रूप से स्वागत करता हूँ कि ... मुझे यकीन नहीं है कि व्यवहार्यता क्या है। मैं इसे .NET फाउंडेशन में उठा सकता हूँ, हालांकि ...
जॉन स्कीट

39

चीजों को लपेटने के लिए । मुझे लगता है कि ज्यादातर लोग जो मेरी तरह यहां आए थे, वे बिना किसी पुस्तकालयों का उपयोग किए और सबसे अच्छा संभव प्रदर्शन के बिना सबसे सरल समाधान चाहते हैं ।

(मेरे विचार से मेरे लिए विधि द्वारा स्वीकृत समूह प्रदर्शन के मामले में एक ओवरकिल है।)

यहां IEqualityComparer इंटरफ़ेस का उपयोग करते हुए एक सरल विस्तार विधि है जो शून्य मानों के लिए भी काम करता है।

उपयोग:

var filtered = taskList.DistinctBy(t => t.TaskExternalId).ToArray();

एक्सटेंशन विधि कोड

public static class LinqExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
    {
        GeneralPropertyComparer<T, TKey> comparer = new GeneralPropertyComparer<T,TKey>(property);
        return items.Distinct(comparer);
    }   
}
public class GeneralPropertyComparer<T,TKey> : IEqualityComparer<T>
{
    private Func<T, TKey> expr { get; set; }
    public GeneralPropertyComparer (Func<T, TKey> expr)
    {
        this.expr = expr;
    }
    public bool Equals(T left, T right)
    {
        var leftProp = expr.Invoke(left);
        var rightProp = expr.Invoke(right);
        if (leftProp == null && rightProp == null)
            return true;
        else if (leftProp == null ^ rightProp == null)
            return false;
        else
            return leftProp.Equals(rightProp);
    }
    public int GetHashCode(T obj)
    {
        var prop = expr.Invoke(obj);
        return (prop==null)? 0:prop.GetHashCode();
    }
}

19

नहीं, इसके लिए ऐसी कोई विस्तार विधि अधिभार नहीं है। मैंने इस निराशा को अतीत में पाया है और इस समस्या से निपटने के लिए मैं आमतौर पर एक सहायक वर्ग लिखता हूं। लक्ष्य को एक में परिवर्तित करना Func<T,T,bool>है IEqualityComparer<T,T>

उदाहरण

public class EqualityFactory {
  private sealed class Impl<T> : IEqualityComparer<T,T> {
    private Func<T,T,bool> m_del;
    private IEqualityComparer<T> m_comp;
    public Impl(Func<T,T,bool> del) { 
      m_del = del;
      m_comp = EqualityComparer<T>.Default;
    }
    public bool Equals(T left, T right) {
      return m_del(left, right);
    } 
    public int GetHashCode(T value) {
      return m_comp.GetHashCode(value);
    }
  }
  public static IEqualityComparer<T,T> Create<T>(Func<T,T,bool> del) {
    return new Impl<T>(del);
  }
}

यह आपको निम्नलिखित लिखने की अनुमति देता है

var distinctValues = myCustomerList
  .Distinct(EqualityFactory.Create((c1, c2) => c1.CustomerId == c2.CustomerId));

8
हालांकि एक बुरा हैश कोड कार्यान्वयन है। IEqualityComparer<T>एक प्रक्षेपण से बनाना आसान है : stackoverflow.com/questions/188120/…
जॉन स्कीट

7
(हैश कोड के बारे में मेरी टिप्पणी को समझाने के लिए - इस कोड के साथ इक्वल्स (x, y) == सत्य के साथ समाप्त करना बहुत आसान है, लेकिन GetHashCode (x)! = GetHashCode (y)। यह मूल रूप से हैशटेबल की तरह टूट जाता है। ।)
जॉन स्कीट

मैं हैश कोड आपत्ति से सहमत हूं। फिर भी, पैटर्न के लिए +1।
Tor Haugen

@, हाँ, मैं मानता हूँ कि GetHashcode का मूल कार्यान्वयन इष्टतम से कम है (आलसी हो रहा था)। मैंने इसे अनिवार्य रूप से अब EqualityComparer <T> .Default.GetHashcode () का उपयोग करने के लिए बदल दिया है जो थोड़ा बहुत मानक है। हालांकि, इस परिदृश्य में GetHashcode कार्यान्वयन के लिए काम करने की गारंटी केवल एक निरंतर मूल्य वापस करने के लिए है। हैशटेबल लुकअप को मारता है लेकिन कार्यात्मक रूप से सही होने की गारंटी है।
JaredPar

1
@JaredPar: बिल्कुल हैश कोड आपके द्वारा उपयोग किए जा रहे समानता फ़ंक्शन के अनुरूप होना चाहिए, जो संभवतः डिफ़ॉल्ट नहीं है अन्यथा आप परेशान नहीं होंगे :) यही कारण है कि मैं एक प्रक्षेपण का उपयोग करना पसंद करता हूं - आप समानता और एक समझदार हैश दोनों प्राप्त कर सकते हैं इस तरह से कोड। इससे कॉलिंग कोड में दोहराव भी कम होता है। बेशक यह केवल उन मामलों में काम करता है जहां आप एक ही प्रक्षेपण को दो बार चाहते हैं, लेकिन यह है कि हर मामला मैंने अभ्यास में देखा है :)
जॉन स्कीट

18

आशुलिपि समाधान

myCustomerList.GroupBy(c => c.CustomerId, (key, c) => c.FirstOrDefault());

1
क्या आप कुछ स्पष्टीकरण जोड़ सकते हैं कि इसमें सुधार क्यों किया गया है?
कीथ पिंसन

यह वास्तव में मेरे लिए अच्छी तरह से काम किया जब कोनराड ने नहीं किया।
20 नवंबर

13

यह वही करेगा जो आप चाहते हैं लेकिन मुझे प्रदर्शन के बारे में पता नहीं है:

var distinctValues =
    from cust in myCustomerList
    group cust by cust.CustomerId
    into gcust
    select gcust.First();

कम से कम यह क्रिया नहीं है।


12

यहाँ एक सरल विस्तार विधि है जो मुझे चाहिए ...

public static class EnumerableExtensions
{
    public static IEnumerable<TKey> Distinct<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector)
    {
        return source.GroupBy(selector).Select(x => x.Key);
    }
}

यह शर्म की बात है कि उन्होंने इस तरह की एक अलग पद्धति को ढांचे में नहीं बांधा, लेकिन हे हो।


यह उस पुस्तकालय morelinq को जोड़ने के बिना सबसे अच्छा समाधान है।
टोडरमो

लेकिन, मुझे बदलना पड़ा x.Keyकरने के लिए x.First()और करने के लिए दिया गया मान बदलIEnumerable<T>
toddmo

@toddmo प्रतिक्रिया के लिए धन्यवाद :-) हाँ, तार्किक लगता है ... मैं आगे की जांच करने के बाद उत्तर को अपडेट करूंगा।
डेविड किर्कलैंड

1
समाधान के लिए धन्यवाद कहने में कभी देर नहीं
अली

4

कुछ मैंने इस्तेमाल किया है जो मेरे लिए अच्छा काम किया है।

/// <summary>
/// A class to wrap the IEqualityComparer interface into matching functions for simple implementation
/// </summary>
/// <typeparam name="T">The type of object to be compared</typeparam>
public class MyIEqualityComparer<T> : IEqualityComparer<T>
{
    /// <summary>
    /// Create a new comparer based on the given Equals and GetHashCode methods
    /// </summary>
    /// <param name="equals">The method to compute equals of two T instances</param>
    /// <param name="getHashCode">The method to compute a hashcode for a T instance</param>
    public MyIEqualityComparer(Func<T, T, bool> equals, Func<T, int> getHashCode)
    {
        if (equals == null)
            throw new ArgumentNullException("equals", "Equals parameter is required for all MyIEqualityComparer instances");
        EqualsMethod = equals;
        GetHashCodeMethod = getHashCode;
    }
    /// <summary>
    /// Gets the method used to compute equals
    /// </summary>
    public Func<T, T, bool> EqualsMethod { get; private set; }
    /// <summary>
    /// Gets the method used to compute a hash code
    /// </summary>
    public Func<T, int> GetHashCodeMethod { get; private set; }

    bool IEqualityComparer<T>.Equals(T x, T y)
    {
        return EqualsMethod(x, y);
    }

    int IEqualityComparer<T>.GetHashCode(T obj)
    {
        if (GetHashCodeMethod == null)
            return obj.GetHashCode();
        return GetHashCodeMethod(obj);
    }
}

@ मूकस मुझे यकीन नहीं है कि आप यहां कक्षा के नाम के बारे में क्यों पूछ रहे हैं। मुझे IEqualityComparer को लागू करने के लिए कक्षा को कुछ नाम देने की आवश्यकता थी, इसलिए मैंने सिर्फ My को उपसर्ग किया।
क्लेनक्स

4

मैंने यहां देखे गए सभी समाधान पहले से ही तुलनीय क्षेत्र का चयन करने पर भरोसा करते हैं। यदि किसी को एक अलग तरीके से तुलना करने की आवश्यकता है, हालांकि, यहां यह समाधान आम तौर पर काम करने के लिए लगता है, जैसे कुछ:

somedoubles.Distinct(new LambdaComparer<double>((x, y) => Math.Abs(x - y) < double.Epsilon)).Count()

लैम्बडाकॉमर क्या है, आप इसे कहां से आयात कर रहे हैं?
पैट्रिक ग्राहम

@PatrickGraham उत्तर में जुड़ा हुआ है: brendan.enrick.com/post/…
दिमित्री लेडेंटसोव

3

दूसरा तरीका अपनाएं:

var distinctValues = myCustomerList.
Select(x => x._myCaustomerProperty).Distinct();

अनुक्रम वापसी के अलग-अलग तत्व उनकी तुलना '_myCaustomerProperty' संपत्ति से करते हैं।


1
यह कहने के लिए यहां आया था। यह स्वीकृत जवाब होना चाहिए
फिर भी।

5
नहीं, यह स्वीकृत उत्तर नहीं होना चाहिए, जब तक कि आप सभी चाहते हैं कि कस्टम संपत्ति के अलग-अलग मूल्य हैं। सामान्य ओपी सवाल यह था कि वस्तु की विशिष्ट संपत्ति के आधार पर अलग-अलग वस्तुओं को कैसे वापस किया जाए ।
तोमो

2

आप InlineComparer का उपयोग कर सकते हैं

public class InlineComparer<T> : IEqualityComparer<T>
{
    //private readonly Func<T, T, bool> equalsMethod;
    //private readonly Func<T, int> getHashCodeMethod;
    public Func<T, T, bool> EqualsMethod { get; private set; }
    public Func<T, int> GetHashCodeMethod { get; private set; }

    public InlineComparer(Func<T, T, bool> equals, Func<T, int> hashCode)
    {
        if (equals == null) throw new ArgumentNullException("equals", "Equals parameter is required for all InlineComparer instances");
        EqualsMethod = equals;
        GetHashCodeMethod = hashCode;
    }

    public bool Equals(T x, T y)
    {
        return EqualsMethod(x, y);
    }

    public int GetHashCode(T obj)
    {
        if (GetHashCodeMethod == null) return obj.GetHashCode();
        return GetHashCodeMethod(obj);
    }
}

उपयोग नमूना :

  var comparer = new InlineComparer<DetalleLog>((i1, i2) => i1.PeticionEV == i2.PeticionEV && i1.Etiqueta == i2.Etiqueta, i => i.PeticionEV.GetHashCode() + i.Etiqueta.GetHashCode());
  var peticionesEV = listaLogs.Distinct(comparer).ToList();
  Assert.IsNotNull(peticionesEV);
  Assert.AreNotEqual(0, peticionesEV.Count);

स्रोत: https://stackoverflow.com/a/5969691/206730
संघ के लिए IEqualityComparer का उपयोग
कर क्या मैं अपने स्पष्ट प्रकार तुलनित्र को निर्दिष्ट कर सकता हूं?


2

आप LambdaEqualityComparer का उपयोग कर सकते हैं:

var distinctValues
    = myCustomerList.Distinct(new LambdaEqualityComparer<OurType>((c1, c2) => c1.CustomerId == c2.CustomerId));


public class LambdaEqualityComparer<T> : IEqualityComparer<T>
    {
        public LambdaEqualityComparer(Func<T, T, bool> equalsFunction)
        {
            _equalsFunction = equalsFunction;
        }

        public bool Equals(T x, T y)
        {
            return _equalsFunction(x, y);
        }

        public int GetHashCode(T obj)
        {
            return obj.GetHashCode();
        }

        private readonly Func<T, T, bool> _equalsFunction;
    }

1

ऐसा करने का एक ट्रिकी तरीका है Aggregate()एक्सटेंशन का उपयोग करना , एक शब्दकोश को कुंजी के रूप में कुंजी-गुण मानों के साथ संचायक के रूप में उपयोग करना:

var customers = new List<Customer>();

var distincts = customers.Aggregate(new Dictionary<int, Customer>(), 
                                    (d, e) => { d[e.CustomerId] = e; return d; },
                                    d => d.Values);

और एक GroupBy शैली समाधान का उपयोग कर रहा है ToLookup():

var distincts = customers.ToLookup(c => c.CustomerId).Select(g => g.First());

अच्छा है, लेकिन सिर्फ एक Dictionary<int, Customer>जगह क्यों नहीं बना ?
रफिन

0

मैं मान रहा हूं कि आपके पास एक IEnumerable है, और आपके उदाहरण के प्रतिनिधि में, आप इस सूची में दो तत्वों का संदर्भ देते हुए c1 और c2 चाहेंगे?

मेरा मानना ​​है कि आप इसे स्वयं से जुड़ सकते हैं var difResults = c1 से myList में शामिल हों c2 से myList में शामिल हों


0

यदि Distinct()अनोखे परिणाम नहीं मिलते हैं, तो इसे आज़माएँ:

var filteredWC = tblWorkCenter.GroupBy(cc => cc.WCID_I).Select(grp => grp.First()).Select(cc => new Model.WorkCenter { WCID = cc.WCID_I }).OrderBy(cc => cc.WCID); 

ObservableCollection<Model.WorkCenter> WorkCenter = new ObservableCollection<Model.WorkCenter>(filteredWC);

0

माइक्रोसॉफ्ट System.Interactive पैकेज है कि एक प्रमुख चयनकर्ता लैम्ब्डा लेता विशिष्ट का एक संस्करण है। यह जॉन स्कीट के समाधान के रूप में प्रभावी रूप से एक ही है, लेकिन यह लोगों को जानने के लिए, और बाकी पुस्तकालय की जांच करने में मददगार हो सकता है।


0

यहाँ आप इसे कैसे कर सकते हैं:

public static class Extensions
{
    public static IEnumerable<T> MyDistinct<T, V>(this IEnumerable<T> query,
                                                    Func<T, V> f, 
                                                    Func<IGrouping<V,T>,T> h=null)
    {
        if (h==null) h=(x => x.First());
        return query.GroupBy(f).Select(h);
    }
}

यह विधि आपको एक पैरामीटर की तरह निर्दिष्ट करके इसका उपयोग करने की अनुमति देती है .MyDistinct(d => d.Name), लेकिन यह आपको एक दूसरे पैरामीटर के रूप में होने की शर्त भी निर्दिष्ट करने की अनुमति देता है:

var myQuery = (from x in _myObject select x).MyDistinct(d => d.Name,
        x => x.FirstOrDefault(y=>y.Name.Contains("1") || y.Name.Contains("2"))
        );

NB यह आपको अन्य कार्यों जैसे उदाहरण के लिए भी निर्दिष्ट करने की अनुमति देगा .LastOrDefault(...)


यदि आप केवल शर्त को उजागर करना चाहते हैं, तो आप इसे लागू करके इसे और भी सरल बना सकते हैं:

public static IEnumerable<T> MyDistinct2<T, V>(this IEnumerable<T> query,
                                                Func<T, V> f,
                                                Func<T,bool> h=null
                                                )
{
    if (h == null) h = (y => true);
    return query.GroupBy(f).Select(x=>x.FirstOrDefault(h));
}

इस स्थिति में, क्वेरी सिर्फ इस तरह दिखाई देगी:

var myQuery2 = (from x in _myObject select x).MyDistinct2(d => d.Name,
                    y => y.Name.Contains("1") || y.Name.Contains("2")
                    );

एनबी यहाँ, अभिव्यक्ति सरल है, लेकिन ध्यान से निहित .MyDistinct2उपयोग करता .FirstOrDefault(...)है।


नोट: ऊपर दिए गए उदाहरण निम्नलिखित डेमो क्लास का उपयोग कर रहे हैं

class MyObject
{
    public string Name;
    public string Code;
}

private MyObject[] _myObject = {
    new MyObject() { Name = "Test1", Code = "T"},
    new MyObject() { Name = "Test2", Code = "Q"},
    new MyObject() { Name = "Test2", Code = "T"},
    new MyObject() { Name = "Test5", Code = "Q"}
};

0

IEnumerable लंबोदर एक्सटेंशन:

public static class ListExtensions
{        
    public static IEnumerable<T> Distinct<T>(this IEnumerable<T> list, Func<T, int> hashCode)
    {
        Dictionary<int, T> hashCodeDic = new Dictionary<int, T>();

        list.ToList().ForEach(t => 
            {   
                var key = hashCode(t);
                if (!hashCodeDic.ContainsKey(key))
                    hashCodeDic.Add(key, t);
            });

        return hashCodeDic.Select(kvp => kvp.Value);
    }
}

उपयोग:

class Employee
{
    public string Name { get; set; }
    public int EmployeeID { get; set; }
}

//Add 5 employees to List
List<Employee> lst = new List<Employee>();

Employee e = new Employee { Name = "Shantanu", EmployeeID = 123456 };
lst.Add(e);
lst.Add(e);

Employee e1 = new Employee { Name = "Adam Warren", EmployeeID = 823456 };
lst.Add(e1);
//Add a space in the Name
Employee e2 = new Employee { Name = "Adam  Warren", EmployeeID = 823456 };
lst.Add(e2);
//Name is different case
Employee e3 = new Employee { Name = "adam warren", EmployeeID = 823456 };
lst.Add(e3);            

//Distinct (without IEqalityComparer<T>) - Returns 4 employees
var lstDistinct1 = lst.Distinct();

//Lambda Extension - Return 2 employees
var lstDistinct = lst.Distinct(employee => employee.EmployeeID.GetHashCode() ^ employee.Name.ToUpper().Replace(" ", "").GetHashCode()); 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.