获取在C#中重复项目的次数

时间:2012-01-13 14:39:05

标签: c# linq list

我正在开发一个程序,用户必须在其中输入某种字符串,程序会将其存储在List或Array中,然后计算该项重复的次数。

重复次数最多的三个项目按重复次数的降序显示(第一次有10次重复,第二次有9次,第三次有8次)

听起来很简单。由于我不知道有多少人会输入字符串,我使用了一个列表,然后按照这个例子:

foreach (string value in list.Distinct())  
{  
    System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", value, list.Count(v => v == value));  
}

但由于某种原因,我的列表名称后面没有出现.Distinct()。我做错什么了吗?这与我的C#有关,这不是C#3.0吗?该示例从未提及有关添加其他引用等的任何内容。

我还有其他办法吗?

5 个答案:

答案 0 :(得分:11)

.Distinct()是LINQ扩展方法。您需要.NET 3.5+才能使用它。

话虽如此,你不需要 LINQ来做你想做的事。您可以轻松地使用其他集合类和一些算术来获得结果。

// Create a dictionary to hold key-value pairs of words and counts
IDictionary<string, int> counts = new Dictionary<string, int>();

// Iterate over each word in your list
foreach (string value in list)
{
    // Add the word as a key if it's not already in the dictionary, and
    // initialize the count for that word to 1, otherwise just increment
    // the count for an existing word
    if (!counts.ContainsKey(value))
        counts.Add(value, 1);
    else
        counts[value]++; 
}

// Loop through the dictionary results to print the results
foreach (string value in counts.Keys)
{
    System.Diagnostics.Debug
        .WriteLine("\"{0}\" occurs {1} time(s).", value, counts[value]);
}

答案 1 :(得分:2)

如果您没有C#3.0,那么您没有扩展方法。

如果您没有.NET3.5,那么您没有任何Linq扩展方法可以作为静态调用。

您可以添加自己的功能中的一小部分:

public static IEnumerable<T> Distinct(IEnumerable<T> src, IEqualityComparer<T> eCmp)
{
  Dictionary<T, bool> fakeHashSet = new Dictionary<T, bool>(eCmp);
  //When I coded for 2.0 I had my own custom HashSet<T>, but that's overkill here
  bool dummy;
  foreach(T item in src)
  {
    if(!fakeHashSet.TryGetValue(item, out dummy))
    {
      fakeHashSet.Add(item, true);
      yield return item;
    }
  }
}
public static IEnumerable<T> Distinct(IEnumerable<T> src)
{
  return Distinct(src, EqualityComparer<T>.Default);
}
public delegate TResult Func<T, TResult>(T arg);//we don't even have this :(
public static int Count(IEnumerable<T> src, Func<T, bool> predicate)
{
  int c = 0;
  foreach(T item in src)
    if(predicate(item))
      ++c;
  return c;
}

因为我们没有扩展语法或lamdbas,所以我们必须将它们称为:

foreach (string value in Distinct(list))  
{  
    System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", value, Count(list, delegate(string v){return v == value;}));  
}

总之,我们可以使用C#2.0实现Linq-to-objects的大部分内容,而且我们很多人都这样做了,但它远没有那么友好,当然我们也无法映射到其他查询提供程序。

在这种情况下,你可以更快地直接进行计数:

Dictonary<string, int> counts = new Dictionary<string, int>();
foreach(string value in list)
{
  if(counts.ContainsKey(value))
    counts[value]++;
  else
    counts[value] = 1;
}
foreach(KeyValuePair<string, int> kvp in counts)
  System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", kvp.Key, kvp.Value));

答案 2 :(得分:0)

您使用的是哪个版本的.NET Framework?包含此方法的最小框架版本是.NET 3.5。

如果您使用的是.NET 3.5或更高版本,那么代码文件中是否有using System.Linq;语句?如果不是,那可能是该方法似乎无法访问的原因。 Distinct方法实际上是Enumerable类中定义的扩展方法,该方法位于System.Linq命名空间中。

答案 3 :(得分:0)

您必须至少使用C#3.0和.NET 3.5,并记住添加using System.Linq;

答案 4 :(得分:0)

与现有解决方案一样,您需要使用.NET 3.5或更高版本才能使用此功能,但无论如何它都在这里;

var query = list.GroupBy(x => x).OrderByDescending(x => x.Count()).Take(3);

foreach (var result in query)
{
    Console.WriteLine("\"{0}\" occurs {1} time(s).", result.Key, result.Count());
}