2015-05-07 43 views
3

我知道我們能找到重複的項目是這樣的:在c#中,如何將字符串和它們的頻率組合到一個結果字符串中?

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

和獨特的項目是這樣的:

var distinctItems = itemStrings.Distinct(); 

但如何將其結合起來,串名單如下:

輸入:a, b, b, c, d, d, d, d

輸出:a, b (2 times), c, d (4 times)

+0

什麼是項目字符串exactl ÿ? 'itemStrings.GroupBy(x => x)'聽起來像是做你想做的事 – Sayse

+4

'.ToDictionary(...)。ToList()'導致我身體上的疼痛 – Rawling

+0

@Sayse List Anatoly

回答

5

你幾乎沒有:

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)); 

如果你想要的結果作爲一個逗號分隔的字符串,然後你可以這樣做:

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

你快到了;你有一些間距和逗號問題 – Rawling

+0

我想刪除最後的'.ToList()',並將'='的整個右側包在一個'string.Join(「」,...)'中給他他在找什麼。 – krillgar

+0

@Rawling真的嗎?這對我來說可以。 – Luaan

1

的東西,如:

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(); 

我添加了一個OrderBy(),因爲您的清單似乎已經訂購了,而且我已經過分簡化了一下,以便緩存x.Count()let cnt = x.Count())。

如果再要一個大的字符串,可以

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

使用'let'好得多,你是對的。我沒有真正使用它,因爲它值得使用:)) – Luaan

2

您已經與第一種方法的解決方案,除去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)); 

另一種方法是使用Enumerable.ToLookup代替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)); 
相關問題