构建列表中项目计数的字典

我有一个包含一堆可以多次出现的字符串的List。 我想获取此列表并构建列表项的字典作为键和它们的出现次数作为值。

例:

List stuff = new List(); stuff.Add( "Peanut Butter" ); stuff.Add( "Jam" ); stuff.Add( "Food" ); stuff.Add( "Snacks" ); stuff.Add( "Philosophy" ); stuff.Add( "Peanut Butter" ); stuff.Add( "Jam" ); stuff.Add( "Food" ); 

结果将是包含以下内容的字典:

 "Peanut Butter", 2 "Jam", 2 "Food", 2 "Snacks", 1 "Philosophy", 1 

我有办法做到这一点,但似乎我没有利用C#3.0中的好东西

 public Dictionary CountStuff( IList stuffList ) { Dictionary stuffCount = new Dictionary(); foreach (string stuff in stuffList) { //initialize or increment the count for this item if (stuffCount.ContainsKey( stuff )) { stuffCount[stuff]++; } else { stuffCount.Add( stuff, 1 ); } } return stuffCount; } 

您可以使用C#中的group子句来执行此操作。

 List stuff = new List(); ... var groups = from s in stuff group s by s into g select new { Stuff = g.Key, Count = g.Count() }; 

如果需要,您也可以直接调用扩展方法:

 var groups = stuff.GroupBy(s => s).Select( s => new { Stuff = s.Key, Count = s.Count() }); 

从这里开始,它是一个简短的跃点,将它放入Dictionary

 var dictionary = groups.ToDictionary(g => g.Stuff, g => g.Count); 

我会创建一个专门的List,由Dictionary支持,add方法将测试成员资格并增加计数(如果找到)。

有点像:

 public class CountingList { Dictionary countingList = new Dictionary(); void Add( string s ) { if( countingList.ContainsKey( s )) countingList[ s ] ++; else countingList.Add( s, 1 ); } } 

一个想法是给字典一个默认值零,所以你不必在特殊情况下第一次出现。

嗯,没有更好的方法来做到这一点。

也许您可以编写一个LINQ查询来对字符串进行分组,然后计算每个组中有多少字符串,但这不会像您现有的那样有效。

 Dictionary a = stuff.GroupBy(p => p).OrderByDescending(r=>r.Count()).ToDictionary(q => q.Key, q => q.Count()); 

您可以通过GroupBy然后创建字典来计算每个组。 正如性能测试所表明的那样,除了Linq之外,通常还有更有效的方法。 我认为您的代码更有效,而Linq解决方案更具可读性和美观性。