views:

70

answers:

3

Let's I have a method to remove duplicates in an integer Array

 public int[] RemoveDuplicates(int[] elems)
    {
        HashSet<int> uniques = new HashSet<int>();
        foreach (int item in elems)
            uniques.Add(item);
        elems = new int[uniques.Count];
        int cnt = 0;
        foreach (var item in uniques)
            elems[cnt++] = item;
        return elems;
    }

How can I make this generic such that now it accepts a string array and remove duplicates in it? How about a double array? I know I am probably mixing things here in between primitive and value types. For your reference the following code won't compile

 public List<T> RemoveDuplicates(List<T> elems)
        {
            HashSet<T> uniques = new HashSet<T>();
            foreach (var item in elems)
                uniques.Add(item);
            elems = new List<T>();
            int cnt = 0;
            foreach (var item in uniques)
                elems[cnt++] = item;
            return elems;
        }

The reason is that all generic types should be closed at run time. Thanks for you comments

+5  A: 
    public List<T> RemoveDuplicates<T>(List<T> elems)
    {                           //  ^
        HashSet<T> uniques = new HashSet<T>();
        foreach (var item in elems)
            uniques.Add(item);
        elems = new List<T>();
        int cnt = 0;
        foreach (var item in uniques)
            elems[cnt++] = item;
        return elems;
    }

Then you call it:

.RemoveDuplicates<string>(new List<string>{ "hello", "hello", "world" });

However, I suggest you use this code:

public IList<T> RemoveDuplicates<T>(IEnumerable<T> elems)
{                            //  ^
    IList<T> uniques = new List<T>();
    foreach(T item in elems)
       if(!uniques.Contains(item))
          uniques.Add(item);

    return uniques;
}

This way

  1. Your function can take any IEnumerable (this include IList, or anything we can enumerate through)
  2. Your function is simpler, it may not be efficient for large data-sets though, however that is subject to your average data-size. If you desire efficiency over large data-sets you can simply take the IEnumerable<> component and go from there.
  3. It returns an IList<>, which is more generic to work with.

Or if you have access to .NET 3.0 / 3.5 / 4.0, use linq like the other answers suggested. Hopefully this helped illustrate Generic Methods.

Aren
What is the downvote for?
Robert Harvey
I'd like to know too... LINQ may be the best overall solution, but this answers his question directly.
Aren
I got downvoted the other day between edits. Downvoters should be re-presented with the answer after edits.
Jay
Thank you Aren I was reading C# Nutshell book but couldn't figure out. I know there are functions like Distinct() but this is an interview question so I'd have to go through the logic :)
satyajit
No problem satyajit, glad I could help.
Aren
+1  A: 

If what you want to return a collection with duplicates removed, the functionality is built-in:

elems = elems.Distinct()

If the question is more generally about creating a generic function that works with strings, ints, doubles, etc., declare it

public IEnumerable<T> RemoveDuplicates(IEnumerable<T> elems) where T : IComparable<T>
Jay
+1  A: 

Easier than writing your own function: .Distinct().ToList().

Stephen Cleary