Reputation:
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
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
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
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