C # extensions-Basic Part 8: Distinct extensions

Source: Internet
Author: User

 

Imagine if you can write it as follows:

Var p1 = products. Distinct (p => p. ID );

Var p2 = products. Distinct (p => p. Name );

Using a simple lambda as a parameter also conforms to the consistent style of Linq.

You can achieve this by using the extension method:

Distinct Extension Method

First, create a general comparison class to implement the IEqualityComparer <T> interface:

Using System;

Using System. Collections. Generic;

Using System. Runtime. CompilerServices;

Using System. Linq;

 

Public class CommonEqualityComparer <T, V>: IEqualityComparer <T>

{

Private Func <T, V> keySelector;

 

Public CommonEqualityComparer (Func <T, V> keySelector)

{

This. keySelector = keySelector;

}

 

Public bool Equals (T x, T y)

{

Return EqualityComparer <V>. Default. Equals (keySelector (x), keySelector (y ));

}

 

Public int GetHashCode (T obj)

{

Return EqualityComparer <V>. Default. GetHashCode (keySelector (obj ));

}

}

In row 3, The EqualityComparer <T> class is used. This article provides a brief description.

With the help of the above class, the Distinct extension method is very easy to write:

1

Public static class DistinctExtensions

{

Public static IEnumerable <T> Distinct <T, V> (this IEnumerable <T> source, Func <T, V> keySelector)

{

Return source. Distinct (new CommonEqualityComparer <T, V> (keySelector ));

}

}

It's easy!

Example of Distinct

Based on ID:

Var data1 = new Person [] {

New Person {ID = 1, Name = "Crane chongtian "},

New Person {ID = 1, Name = "ldp "}

};

Var ps1 = data1

. Distinct (p => p. ID)

. ToArray ();

According to Name:

Var data2 = new Person [] {

New Person {ID = 1, Name = "Crane chongtian "},

New Person {ID = 2, Name = "Crane chongtian "}

};

Var ps2 = data2

. Distinct (p => p. Name)

. ToArray ();

After reading the reply, I made some improvements and recommended the following methods:

Improvement

A friend mentioned in the reply that "it is not difficult to exclude duplicate strings without case sensitivity". You just need to improve the code above and then OK:

CommonEqualityComparer <T, V> class:

Using System;

Using System. Collections. Generic;

Using System. Runtime. CompilerServices;

Using System. Linq;

 

Public class CommonEqualityComparer <T, V>: IEqualityComparer <T>

{

Private Func <T, V> keySelector;

Private IEqualityComparer <V> comparer;

 

Public CommonEqualityComparer (Func <T, V> keySelector, IEqualityComparer <V> comparer)

{

This. keySelector = keySelector;

This. comparer = comparer;

}

 

Public CommonEqualityComparer (Func <T, V> keySelector)

: This (keySelector, EqualityComparer <V>. Default)

{}

 

Public bool Equals (T x, T y)

{

Return comparer. Equals (keySelector (x), keySelector (y ));

}

 

Public int GetHashCode (T obj)

{

Return comparer. GetHashCode (keySelector (obj ));

}

}

Distinct extension method:

Public static class DistinctExtensions

{

Public static IEnumerable <T> Distinct <T, V> (this IEnumerable <T> source, Func <T, V> keySelector)

{

Return source. Distinct (new CommonEqualityComparer <T, V> (keySelector ));

}

 

Public static IEnumerable <T> Distinct <T, V> (this IEnumerable <T> source, Func <T, V> keySelector, IEqualityComparer <V> comparer)

{

Return source. Distinct (new CommonEqualityComparer <T, V> (keySelector, comparer ));

}

}

With optional parameters, the two extension methods can also combine one:

Public static IEnumerable <T> Distinct <T, V> (this IEnumerable <T> source, Func <T, V> keySelector,

IEqualityComparer <V> comparer = EqualityComparer <V>. Default)

{

Return source. Distinct (new CommonEqualityComparer <T, V> (keySelector, comparer ));

}

(Likewise, the two constructors of the CommonEqualityComparer <T, V> class can be combined into one)

Example:

Var data3 = new Person [] {

New Person {ID = 1, Name = "LDP "},

New Person {ID = 2, Name = "ldp "}

};

Var ps3 = data3

. Distinct (p => p. Name, StringComparer. CurrentCultureIgnoreCase)

. ToArray ();

EqualityComparer <T> class description

EqualityComparer <T> provides a base class for The Implementation of The IEqualityComparer <T> generic interface. It has five important sub-classes in. net 4. See:

These five subclasses use the equality comparison of different types of data. We can know a little about the class name.

These five subclasses are internal classes (internal) and cannot be accessed directly. The EqualityComparer <T> class provides a simple property Default. EqualityComparer <T> loads different subclasses based on the input T type and caches them to improve performance.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.