A.F.N
A.F.N

Reputation: 196

How change a list of array of strings to a list of string

I have a list of products and every product have a string filed that is contain a list of tags that are concate with "#" character like this:

Tag1#Tage2#Tag3

I need to get all tags and order them by their number of their repeats.

I actually did this like this:

List<string> t = new List<string>();

var tags = (from p in db.Products
                    where p.Active
                    select p.Tags
                    ).ToList();

foreach (var item in tags)
{
   if (item == null)
      continue;
   var d = item.Split('#');
   foreach (var item2 in d)
   {
      t.Add(item2);
   }
}

var ans = t.GroupBy(p => new { id = p }).Select(g => new { id = g.Key.id, total = g.Count() }).OrderByDescending(g => g.total).ToList();

but im sure its not simple (and maybe optimized). Can someone help me to make this code simpler and better? for example with Linq statement etc..

Upvotes: 0

Views: 63

Answers (1)

Alexey.Petriashev
Alexey.Petriashev

Reputation: 1734

Here's my variant:

using System;
using System.Linq;

namespace TagsSplitExample
{
    public class Product
    {
        public bool Active { get; set; }
        public string Tags { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var products = new[]
            {
                new Product{ Active = true, Tags = "Tag1"},
                new Product{ Active = true, Tags = "Tag1#Tag2"},
                new Product{ Active = true, Tags = "Tag1#Tag2#Tag3"},
            };

            var allTags = products
                .Where(p => p.Active && p.Tags != null)
                .Select(p => p.Tags)
                .Select(tags => tags.Split('#'))
                .SelectMany(tag => tag)
                .GroupBy(tag => tag)
                .Select(group => new { Tag = group.Key, Count = group.Count() })
                .OrderByDescending(pair => pair.Count)
                .ToList();

            allTags.ForEach(pair => Console.WriteLine($"{pair.Tag} : {pair.Count}"));

            Console.ReadLine();
        }
    }
}

Final ToList() can be omitted if you just need to enumerate result.

Result:

Tag1 : 3
Tag2 : 2
Tag3 : 1

Upvotes: 2

Related Questions