Search code examples
c#dictionarycontainskey

Is it common practice to use dictionary to check unique element in the list?


Say I have a list of objects, object Fruit. Fruit has a property Name. i.e. Fruit1.Name = "Apple", Fruit2.Name = "Orange", Fruit3.Name = "Apple", Fruit4.Name = "Melon"... etc

List<Fruit> Basket = {Fruit1, Fruit2, Fruit3, Fruit4, Fruit 5...... Fruit 100}.

I want to have a list of Unique Fruits, where every fruit in the list has unique name. I want to optimize for time. I've seen some people do the following. Is this a best way?

public List<Fruit> GetUniqueFruits(List<Fruit> Basket)
{
    Dictionary<string, Fruit> tempUniqueFruits = new Dictionary<string, Fruit>();
    List<Fruit> uniqueFruits = new List<Fruit>();
    foreach(var fruit in Basket)
    {
        if (!tempUniqueFruits.ContainsKey(fruit.Name)
        {
            tempUniqueFruits.Add(fruit.Name, fruit);
            uniqueFruits.Add(fruit);
        }
    }
    return uniqueFruits;
}

I hear dictionary lookup is very fast, so I guess maybe that's why this is used, but I want to know if there is a better way.

Thanks matt burland, i fixed the typo. ( coulnd't comment yet)


Solution

  • You can use an IEqualityComparer to clarify the code.

    public List<Fruit> GetUniqueFruits(List<Fruit> Basket) {
        var set = new HashSet<Fruit>(Basket, new FruitNameEqualityComparer());
        return set.ToList();
    }
    
    public class Fruit {
        public string Name { get; set; }
        public DateTime RipeTime { get; set; }
    }
    
    class FruitNameEqualityComparer : IEqualityComparer<Fruit> {
        public int Compare(Fruit a, Fruit b) {
            return a.Name.CompareTo(b.Name);
        }
    
        public bool Equals(Fruit a, Fruit b) {
            return a.Name.Equals(b.Name);
        }
    
        public int GetHashCode(Fruit f) {
            return f.Name.GetHashCode();
        }
    }
    

    Dictionary<T, U> is best used when you are mapping from keys to values, but if you are only interested in maintaining a set of unique values without any mappings, a HashSet<T> is specifically designed for that purpose.