Reputation: 6047
I want to list all categories of all published posts. But I would like to display categories just once.
The Post
class has a prop Posts
and a constructor for the Categories
prop. It's an string array instead of List and I would like to keep it that way.
public class Post
{
public static List<Post> Posts = LoadPosts();
}
public Post()
{
ID = Guid.NewGuid().ToString();
Categories = new string[0]; //array, no List<string>
}
This is my razor markup
<ul class="categories">
@{var cl = Post.Posts.Where(p => p.IsPublished).Select(c => new List<string>(c.Categories));}
@foreach (var cat in cl.Distinct())
{
<li>@cat</li>
}
</ul>
This gives me as output
System.Collections.Generic.List`1[System.String]
I have done something wrong in my Linq, but I am not experienced enough (or awake) to see my mistake.
Upvotes: 1
Views: 261
Reputation: 30892
What you need is the SelectMany
method:
Post.Posts
.Where(p => p.IsPublished) // IEnumerable<Post>
.SelectMany(c => c.Categories) // IEnumerable<string>
.Distinct()
It seems odd, but the real counterpart to the SQL select
is not the IEnumerable.Select
method, but the IEnumerable.SelectMany
, because it can "flatten" the result of the selection, while Select
makes a separate collection for each element, resulting in:
Post.Posts
.Where(p => p.IsPublished) // IEnumerable<Post>
.Select(c => c.Categories) // IEnumerable<IEnumerable<string>>
.Distinct() // does nothing, since all inner IEnumerable<string>
// objects are different
Upvotes: 3