【问题标题】:Getting the number of times an item is repeated in C#获取项目在 C# 中重复的次数
【发布时间】:2012-01-13 14:39:05
【问题描述】:

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

然后按照重复次数的降序显示重复次数最多的三个项目(第一个有10个重复,第2个有9个,第3个有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)有关吗?该示例从未提及任何有关添加其他引用等的内容。

有没有其他方法可以做到这一点?

【问题讨论】:

  • 如果您使用的是 3.0 之前的版本,您将无法访问 Distinct 扩展方法。
  • 您的预期结果是什么,您看到的结果是什么?
  • 只是 .NET 2.0。很遗憾。对不起,我忘了提。
  • 列出什么?很可能您在不区分相等性的对象上应用 distinct... 您可以使用 IEquatable 或 IEqualityComparer stackoverflow.com/questions/1365748/… 解决此问题

标签: c# linq list


【解决方案1】:

.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]);
}

【讨论】:

  • @ThomasLevesque:谢谢,我最初是这样想的,但后来自己猜到了。
  • 和对 system.core.dll 的引用
  • 天哪。那么我是否只下载最新版本的 .NET?或者这会弄乱我的 Visual Studio 2005 吗?
  • @zack_falcon:它不会弄乱 VS2005,但你必须升级到 VS2008。您可以从 MSDN 下载 Microsoft .NET Framework 3.5 SP1。
  • 嗯,就是这样。这就是我害怕的。你会建议什么其他的收藏类?我可以想出一个 For Loop 解决方案,但它可能效率不高。
【解决方案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));

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        与您现有的解决方案一样,您需要 .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());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-26
          • 2013-09-25
          • 2013-02-10
          • 1970-01-01
          • 1970-01-01
          • 2019-09-21
          • 2012-12-13
          • 2014-11-01
          相关资源
          最近更新 更多