2009-07-16 2 views
37

Есть ли простой способ подсчета количества вхождений всех элементов списка в тот же список в C#?Метод подсчета вхождений в список

Что-то вроде этого:

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

ответ

67

Как о чем-то вроде этого ...

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 на комментарий: Я попытаюсь сделать это справедливость. :)

В моем примере это Func<int, TKey>, потому что мой список - это ints. Итак, я рассказываю GroupBy, как группировать свои предметы. Func принимает int и возвращает ключ для моей группировки. В этом случае я получу IGrouping<int,int> (группировка ints с ключом int). Если бы я изменил его на (i => i.ToString()), например, я бы привязал свою группу к строке. Вы можете представить себе менее тривиальный пример, чем манипулирование «1», «2», «3» ... возможно, я создаю функцию, которая возвращает «один», «два», «три», чтобы быть моими ключами ...

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

Итак, это Func, который будет принимать Int и возвращает строку, так же, как ...

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

Но, так как оригинальный вопрос призвал зная исходное значение списка и его количества, Я просто использовал целое число, чтобы закрепить свою целую группировку, чтобы упростить мой пример.

+1

+1. это очень элегантно, чтобы считать появление каждого отдельного элемента. –

+0

Как насчет list.FindAll? – CodeFusionMobile

+0

FindAll возвращает список элементов из исходного списка, который соответствует предикату, поэтому вам нужно будет сделать это один раз для каждого уникального элемента, чтобы найти счетчик для этого элемента. –

-1

Ваш внешний цикл зациклился на все слова в списке. Это не нужно и вызовет проблемы. Удалите его, и он должен работать правильно.

7

Вы можете сделать что-то подобное, чтобы рассчитывать на список вещей.

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

Рассчитывать одного элемента

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

int count = words.Where(x => x.Equals(occur)).Count(); 
+1

+1: Мне потребовалось некоторое время, чтобы выяснить, что GetMethods() был только ваш список вещей. :) –

+0

Да, я подумал об этом и решил сделать его более читаемым. спасибо, хотя я неправильно понял вопрос. Он говорит, чтобы считать «весь элемент» .. ooops. Это должно быть достаточно полезным. –

+0

@StanR. - это решение работает для моей проблемы. Однако существует ли метод в списке, в котором я могу считать, что встречание больше или равно словам? Я использую тип «int» вместо «string». –

11
var wordCount = 
    from word in words 
    group word by word into g 
    select new { g.Key, Count = g.Count() };  

Это взято из одного из примеров в LINQPad

Смежные вопросы