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