【问题标题】:use LINQ to find the product with the cheapest value?使用 LINQ 找到价值最低的产品?
【发布时间】:2012-06-06 10:56:24
【问题描述】:

我正在学习 LINQ,我想从以下列表中找到最便宜的产品:

List<Product> products = new List<Product> { 
                new Product {Name = "Kayak", Price = 275M, ID=1}, 
                new Product {Name = "Lifejacket", Price = 48.95M, ID=2}, 
                new Product {Name = "Soccer ball", Price = 19.50M, ID=3}, 
            };

我想出了以下方法,但不知何故感觉这不是最好的方法:

var cheapest = products.Find(p => p.Price == products.Min(m => m.Price));

你能告诉我实现这一目标的正确方法吗?

【问题讨论】:

标签: c# linq


【解决方案1】:

你应该使用MinBy:

public static TSource MinBy<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, IComparable> projectionToComparable
) {
    using (var e = source.GetEnumerator()) {
        if (!e.MoveNext()) {
            throw new InvalidOperationException("Sequence is empty.");
        }
        TSource min = e.Current;
        IComparable minProjection = projectionToComparable(e.Current);
        while (e.MoveNext()) {
            IComparable currentProjection = projectionToComparable(e.Current);
            if (currentProjection.CompareTo(minProjection) < 0) {
                min = e.Current;
                minProjection = currentProjection;
            }
        }
        return min;                
    }
}

只需将此作为方法添加到 public static 类 (EnumerableExtensions?) 中。

现在你可以说

var cheapest = products.MinBy(x => x.Price);

【讨论】:

    【解决方案2】:

    或者,您可以简单地对它们进行排序并获取第一个结果,这是假设您在 Product 对象之后而不是 Price 值之后;像这样。

    var cheapestProduct = products.OrderBy(p => p.Price).FirstOrDefault();
    var mostExpensiveProduct = products.OrderByDescending(p => p.Price).FirstOrDefault();
    

    【讨论】:

    • 这是O(n log n),因为O(n) 是可能的。事实上,OP 的解决方案已经是O(n) 它只是有一个缺点,它必须扫描列表两次。事实上,可以只扫描一次列表,就好像我们在计算最低价格一样。但相反,我们会以最低价格跟踪产品:stackoverflow.com/a/10912887/45914
    • @Jaon:我看不出 OP 在哪里提到他需要尽可能快的实现。也许使用足够快的最简单就足够了?!
    • @TimSchmelter,在这种情况下,为什么要使用LINQ。一个简单的ForEach 也不够吗?我认为看性能总是好的,当然我们不想发疯,但记住它并不是一个坏习惯。
    • @FrançoisWahl:因为 LINQ 的主要优势可读性。所以实际上 "simple" ForEach 在大多数情况下比简单的 LINQ 查询更难维护和理解。但无论如何,MinBy 方法是可读的(如果隐藏在扩展方法中)并且可以更快。
    • @Tim Schmelter:有一个非常简单、直接的O(n) 算法,它易于编码、易于理解且易于使用。没有理由改用算法复杂度更差的算法。
    【解决方案3】:

    您需要先按价格订购,然后选择第一个。

    if(products.Any()){
        var productWithCheapestPrice = products.OrderBy(p => p.Price).First();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 2015-11-05
      • 2013-01-14
      相关资源
      最近更新 更多