Harry Fischer
Harry Fischer

Reputation: 29

Having trouble grabbing values from groupby

So I am trying to grab two values from 2 different collections, the user collection which holds the names i need and the Post collection which holds the scores needed. I am trying to create a LINQ query that grabs all the post a user has posted, by comparing ID's, and then getting the lowest post score from that user. Here is what I have so far:

This prints what the 2 values I need but wont group them by Min value.

 var lowestQuery =
                from user in Assignment1.userDict
                from post in Assignment1.allPosts
                where user.Value.ID == post.AuthorID
                orderby user.Value.Name ascending
                group post.Score by new { user.Value.Name, post.Score } into scores
                select new
                {
                    name = scores.Key,
                    lowestScore = scores.Min()
                };

Basically just need the users lowest post but I am having trouble doing that with grouping two values. When I just group by user.value.Name I am able to get the list of names correctly but not the Score since it doesnt exist in scores that i created with the groupby statement. Any help would be appreciated

Upvotes: 0

Views: 43

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112342

Combining the users and the posts like this is going to have a bad performance. Since the two from clauses create nested loops, you will have a time complexity of O(n^2). Better use a group join

var lowestQuery = from user in Assignment1.userDict.Values
    join post in Assignment1.allPosts on user.ID equals post.AuthorID into posts
    select new {
        name = user.Name,
        lowestScore = posts.DefaultIfEmpty().Select(p => p?.Score).Min()
    };

Note that the Min method will throw an exception if the collection is empty. DefaultIfEmpty creates null item. p?.Score returns a nullable value. It will be null if p is null. See: Null-conditional operators ?. and ?[]

Upvotes: 0

Canica
Canica

Reputation: 2738

Since you are only interested in grouping by the user name, adjust your group by clause to group only by the user name and return post records (I renamed to posts since you are retrieving post records):

group post by user.Value.Name into posts

Then in your select you can use your posts group to select the Min score:

select new
{
     name = posts.Key,
     lowestScore = posts.Min(p => p.Score)
};

HTH

Upvotes: 1

Related Questions