BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

LINQ
.NET 3.5+

A LINQ Style Duplicate Item Finder

Language-Integrated Query (LINQ) includes a number of set operators, including one that removes duplicates from a sequence to return only distinct values. This article describes a custom set operator that returns only the duplicated values from a list.

Adding the Overloads

To complete the class we need to add the three remaining overloaded versions of the method. For the overloads that don't include a comparer, we use the default comparer for the type specified in the generic type parameter. For those that don't include the returnAll flag, we pass true to return every duplicate.

public static IEnumerable<T> Duplicates<T>(this IEnumerable<T> sequence)
{
    return sequence.Duplicates(EqualityComparer<T>.Default, true);
}

public static IEnumerable<T> Duplicates<T>(this IEnumerable<T> sequence, bool returnAll)
{
    return sequence.Duplicates(EqualityComparer<T>.Default, returnAll);
}

public static IEnumerable<T> Duplicates<T>(
    this IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
    return sequence.Duplicates(comparer, true);
}

Calling the Methods

We can now try the four versions of the method using the code below. The first use returns all of the exact duplicates from an array of strings. The second returns only one of each duplicate. The third and fourth calls repeat the first and second using case-insensitive comparisons.

var sequence = new string[] { "A", "a", "B", "C", "D", "D", "d", "E" };

var duplicates1 = sequence.Duplicates();
var duplicates2 = sequence.Duplicates(false);
var duplicates3 = sequence.Duplicates(StringComparer.OrdinalIgnoreCase);
var duplicates4 = sequence.Duplicates(StringComparer.OrdinalIgnoreCase, false);

/* RESULTS

duplicates1 = { "D", "D" }
duplicates2 = { "D" }
duplicates3 = { "A", "a", "D", "D", "d" }
duplicates4 = { "A", "D" }

*/
18 October 2012