Mike McCoy
Mike McCoy

Reputation: 797

C# Order List based on average of nested list value with lambda expression

I'm wondering if it is possible to use a lambda expression to order a list of items based on the average value of a nested list of items.

In project terms, I have a list of products that each can have many reviews. I want to order the list of the products based on the average rating from each product's list of reviews.

I have this:

products = category.Products.OrderBy(i => i.Reviews.Average(x => x.Rating));

This builds without a problem but when I run it, it returns an error that says

Sequence contains no elements

Is it possible to do this with a lambda expression?

Upvotes: 0

Views: 1097

Answers (2)

Tim Schmelter
Tim Schmelter

Reputation: 460148

Enumerable.Average throws the InvalidOperationException because the sequence contains no elements since a product has no Reviews.

You could use Enumerable.DefaultIfEmpty(customValue):

products = category.Products
    .OrderBy(i => i.Reviews.Select(r => r.Rating).DefaultIfEmpty(0).Average());

Maybe you want to exclude these products from the result:

products = category.Products
    .Where(p => p.Reviews.Any())
    .OrderBy(p => p.Reviews.Average(r => r.Rating));

Upvotes: 6

zmbq
zmbq

Reputation: 39013

One of your products probably has no reviews. You should decide what rating to give it, let's say 99 because you want it to appear at the end, so:

category.Products.OrderBy(p=>p.Reviews.Count > 0 ?
                          p.Reviews.Average(r=>r.Rating) : 99);

Upvotes: 2

Related Questions