1

I have a List of BlogPageModel , in List I have string Array of Category.

Model class looks like below:

    public class BlogPageModel : BaseModel
    {
        public string Title { get; set; }
        public string Slug { get; set; }
        public string[] Category { get; set; }
    }

I want list of all Category with blogs count as output, i.e

Travel-20
Entertainment-5

Note: Travel-20 mean 20 blogs are in list which have Travel Category, and Entertainment-5 mean 5 blogs are Entertainment category, remember few blogs have both categories.

I tried to apply GroupBy like below:

_client.GetRecords().Result.GroupBy(x => x.Category).Select(x => new { Key = x.Key })

But it's not working and returning list of blogs.

I also tried below:

enter image description here

I am not sure what I am doing wrong in my query.

4
  • Does Travel-20 mean that 20 BlogPageModel's in your list have the string "Travel" in the Category array? Commented Apr 30, 2020 at 6:38
  • Yes Travel-20 mean 20 blogs are in list which have Travel Category, and Entertainment-5 mean 5 blogs are Entertainment category, remember few blogs have both categories. Commented Apr 30, 2020 at 6:40
  • I don't have C# to test right now, but I think there is some sort of Count() or similar method to put after Select() Commented Apr 30, 2020 at 6:43
  • Category should be called Categories. Collections should have a plural name Commented Apr 30, 2020 at 7:10

2 Answers 2

2

Firstly flatten the result using SelectMany. You should use GroupBy Again to grouping the tags by key and finally count them like this:

var result = _client.GetRecords().Result
                .SelectMany(x => x.Category)
                .GroupBy(x => x)
                .Select(x => $"{x.Key}-{x.Count()}");
Sign up to request clarification or add additional context in comments.

2 Comments

Please add some more words than just "try this". Answers on SO should not promote "coding by trial and error"
Surely the first groupby is a wasted operation then?
2

You can expand the blogs with their list of categories to a new sequence of just the category, before you group it:

_client.GetRecords().Result.SelectMany(blog => blog.Category).GroupBy(x => x.Category).Select(x => x.Key + "-" + x.Count());

x is an IGrouping, basically like a List together with a Key. You can do things on it that you would do on a List, like Count or First. Every item in the list has a common Key, which was chosen as part of the GroupBy. In this case your x where the key is "Travel" is a list of Category 20 long

Incidentally, (assuming GetRecords returns a Task) consider whether you should be using .Result - it blocks the calling thread until the operation is finished which is a great way to nuke all the advantages of task based Async pattern and revert to synchronous code. If you instead await GetRecords (which should be called GetRecordsAsync) then it will free the thread up to go and do other things while the records are being returned

(await _client.GetRecords()).SelectMany(blog => blog.Category).GroupBy(x => x.Category).Select(x => x.Key + "-" + x.Count());

If you want to keep the Blog object after the SelectMany has ended you can use:

(await _client.GetRecords()).SelectMany(b => blog.Category, (b, c) => new { Blog = blog, Cat = c })

You'll get an enumerable that has Nblogs * Ncategories (25 items)

1 Comment

not worked, its not returning correct output, you can see the image in my question, I post there

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.