Getting the number of repetitions of an element in C #

I am working on a program in which the user must enter some string, and the program will store it in a list or array, and then count how many times the element was repeated.

The three elements that are repeated the most are then displayed in descending order of number of repetitions (the first has 10 repetitions, the second has 9, the third has 8)

It sounded simple. Since I have no idea how many people will enter a string, I used a list, and then follow this example:

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

But for some reason .Distinct () does not appear after the name of my list. Did I do something wrong? Is this related to my C #, which is not C # 3.0? The example never mentioned anything about adding another link or the like.

Is there any other way I can do this?

+5
source share
5 answers

.Distinct()- LINQ extension method. Its use requires .NET 3.5+.

With that said, you don't need LINQ to do what you want. You can easily use other collection classes and some arithmetic to get your results.

// 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 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]);
}
+10
source

If you do not have C # 3.0, then you do not have extension methods.

If you do not have .NET3.5, then you do not have any Linq extension methods to call as statics.

You can add your own for some of these features:

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

Since we don't have extension syntax or lamdbas, we should call them like this:

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

, Linq-to-objects # 2.0, , , , , .

, , :

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

.NET Framework ? , , -.NET 3.5.

.NET 3.5 , using System.Linq; ? , , , . Distinct , Enumerable, System.Linq.

0

# 3.0 .NET 3.5, using System.Linq;

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

All Articles