views:

2188

answers:

4

Is there a simple way to count the number of occurences of all elements of a list into that same list in C#? Something like this:

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;

string Occur;
List<string> Words = new List<string>();
List<string> Occurrences = new List<string>();

// ~170 elements added. . . 

for (int i = 0;i<Words.Count;i++){
    Words = Words.Distinct().ToList();
    for (int ii = 0;ii<Words.Count;ii++){Occur = new Regex(Words[ii]).Matches(Words[]).Count;}
         Occurrences.Add (Occur);
         Console.Write("{0} ({1}), ", Words[i], Occurrences[i]);
    }
}
A: 

Your outer loop of looping over all the words in the list is unnecessary and will cause you problems. Remove the outer loop and it looks like what you have should work properly.

McWafflestix
+3  A: 

You can do something like this to count from a list of things.

        IList<String> names = new List<string>() { "ToString", "Format" };
        IEnumerable<String> methodNames = typeof(String).GetMethods().Select(x => x.Name);

        int count = methodNames.Where(x => names.Contains(x)).Count();

To count a single element

    string occur = "Test1";
    IList<String> words = new List<string>() {"Test1","Test2","Test3","Test1"};

    int count = words.Where(x => x.Equals(occur)).Count();
Stan R.
+1: It took me awhile to figure out that GetMethods() was just your list of things. :)
Robert Harvey
yeah, I thought of that and decided to make it more readable. thanks, although I misread the question. It says to count "all the element"..ooops. This should still be useful enough.
Stan R.
+10  A: 

How about something like this ...

var l1 = new List<int>() { 1,2,3,4,5,2,2,2,4,4,4,1 };

var g = l1.GroupBy( i => i );

foreach( var grp in g )
{
  Console.WriteLine( "{0} {1}", grp.Key, grp.Count() );
}

Edit per comment: I will try and do this justice. :)

In my example, it's a Func<int, TKey> because my list is ints. So, I'm telling GroupBy how to group my items. The Func takes a int and returns the the key for my grouping. In this case, I will get an IGrouping<int,int> (a grouping of ints keyed by an int). If I changed it to (i => i.ToString() ) for example, I would be keying my grouping by a string. You can imagine a less trivial example than keying by "1", "2", "3" ... maybe I make a function that returns "one", "two", "three" to be my keys ...

private string SampleMethod( int i )
{
  // magically return "One" if i == 1, "Two" if i == 2, etc.
}

So, that's a Func that would take an int and return a string, just like ...

i =>  // magically return "One" if i == 1, "Two" if i == 2, etc.

But, since the original question called for knowing the original list value and it's count, I just used an integer to key my integer grouping to make my example simpler.

JP Alioto
+1. this is very elegant to count the occurrence of each distinct elements.
Stan R.
What about list.FindAll?
CodeFusionMobile
FindAll returns a list of elements from the original list that match a predicate, so you would have to do it once for each unique element to find the count for that element.
JP Alioto
+4  A: 
var wordCount =
    from word in words
    group word by word into g
    select new { g.Key, Count = g.Count() };

This is taken from one of the examples in the linqpad

Steve Mitcham