0

假设我有一个对象列表 object Fruit。水果有一个属性Name。即Fruit1.Name = "Apple", Fruit2.Name = "Orange", Fruit3.Name = "Apple", Fruit4.Name = "Melon"... 等

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

我想要一个独特水果的列表,列表中的每个水果都有唯一的名称。我想优化时间。我见过一些人这样做。这是最好的方法吗?

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;
}

我听说字典查找非常快,所以我想这可能就是使用它的原因,但我想知道是否有更好的方法。

谢谢马特伯兰,我修正了错字。(还不能评论)

4

4 回答 4

2

您可以使用 anIEqualityComparer来阐明代码。

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>最好在从键映射到值时使用,但如果您只对维护一组唯一值而不需要任何映射感兴趣,则 aHashSet<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 回答
1

因此,如果名称是对象的唯一部分(即键)并且项目的顺序并不重要,那么 aDictionary<string, Fruit>是存储它们的完全有效的方式。另一种选择是HashSet,但是您需要在您的类中实现Equalsand (或创建一个)。GetHashCodeFruitIEqualityComparer<Fruit>

但是对于您的特定代码,您可以使用高效的 Linq 语句(如 Lee 的),但是使用您的特定代码,您无需在构建字典的同时创建唯一项目列表(除非订单很重要)因为您可以退货tempUniqueFruits.Values.ToList()

此外,如果您想构建唯一项目列表(以保留顺序),那么由于您实际上并没有使用字典中的值,只是键,您可以使用 aHashSet<string>代替。

于 2014-03-27T19:51:04.523 回答