user1362208
user1362208

Reputation:

use LINQ to find the product with the cheapest value?

Im learning LINQ and I want to find the cheapest product from the following list:

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

I have come up with the following but somehow it feels like it is not the best way to do it:

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

can you show me the right way to achieve this.

Upvotes: 4

Views: 3401

Answers (3)

jason
jason

Reputation: 241601

You should use 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;                
    }
}

Just add this as a method in a public static class (EnumerableExtensions?).

Now you can say

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

Upvotes: 10

Tim Schmelter
Tim Schmelter

Reputation: 460058

You need to order by the price first and then select the first.

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

Upvotes: 0

Richard
Richard

Reputation: 8280

Alternatively, you could simply order them and take the first result, this is assuming you're after the Product object and not the Price value; like so.

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

Upvotes: 1

Related Questions