In C #, how do I concatenate strings and their frequency with the resulting string?

I know we can find duplicate elements like this:

var dublicateItems = itemStrings.GroupBy(x => x)
                                .Where(x => x.Count() > 1)
                                .ToDictionary(g => g.Key, g => g.Count());

      

And different elements like this:

var distinctItems = itemStrings.Distinct();

      

But how to combine it with the following list of strings:

input: a, b, b, c, d, d, d, d

output: a, b (2 times), c, d (4 times)

+3


source to share


3 answers


You are almost there:

var duplicateItems = 
  itemStrings
  .GroupBy(i => i)
  .Select(i => new { Key = i.Key, Count = i.Count() })
  .Select(i => i.Key + (i.Count > 1 ? " (" + i.Count + " times)" : string.Empty));

      



If you want the result to be comma separated, you can do the following:

var result = string.Join(", ", duplicateItems);

      

+5


source


You already have a solution with the first approach, remove Where

var itemCounts = itemStrings.GroupBy(x => x)
    .ToDictionary(g => g.Key, g => g.Count());

string result = String.Join(", ", 
    itemCounts.Select(kv => kv.Value > 1 
        ? string.Format("{0} ({1} times)", kv.Key, kv.Value) 
        : kv.Key)); 

      



Another approach uses Enumerable.ToLookup

instead GroupBy

:

var itemLookup = itemStrings.ToLookup(x => x);
string result = String.Join(", ",
     itemLookup.Select(grp => grp.Count() > 1 
         ? string.Format("{0} ({1} times)", grp.Key, grp.Count())
         : grp.Key)); 

      

+2


source


With something like:

string[] itemStrings = new[] { "a", "b", "b", "c", "d", "d", "d", "d" };
string[] duplicateItems = (from x in itemStrings.OrderBy(x => x).GroupBy(x => x)
                           let cnt = x.Count()
                           select cnt == 1 ? 
                                  x.Key : 
                                  string.Format("{0} ({1} times)", x.Key, cnt)
                          ).ToArray();

      

I added OrderBy()

because your list seems to be ordered and I complicated it a bit for caching x.Count()

( let cnt = x.Count()

).

If you need one big line, you can

string joined = string.Join(",", duplicateItems);

      

+1


source







All Articles