0

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)

4

4 に答える 4

2

を使用しIEqualityComparerてコードを明確にすることができます。

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>は、キーから値にマッピングする場合に最もよく使用されますが、マッピングを行わずに一意の値のセットを維持することのみに関心がある場合は、HashSet<T>その目的のために特別に設計されています。

于 2014-03-27T19:47:42.367 に答える
1

ディクショナリは、値ではなく一意のキーのみを含むようにコードに強制します。したがって、既に存在する別のキーを追加しようとすると、エラーがスローされます。値を取得したい場合は、辞書がハッシュを使用してルックアップを行うキー名で値を取得するだけでよいため、非常に高速になります。リストを検索したいときは、リスト全体を反復して目的のリストを見つける必要があります。これは、リスト全体を反復しているため、遅くなる可能性があります。

于 2014-03-27T19:44:21.627 に答える
1

より短い方法は次のとおりです。

return Basket.GroupBy(f => f.Name).Select(grp => grp.First()).ToList();

Basketただし、これにより、最初のアイテムが指定された名前で保持されない場合があります。

于 2014-03-27T19:45:06.337 に答える