2009-07-16 58 views
37

Có cách nào đơn giản để đếm số lần xuất hiện của tất cả các phần tử của danh sách vào cùng một danh sách trong C# không?Phương pháp đếm số lần xuất hiện trong danh sách

Something như thế này:

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

Trả lời

67

Làm thế nào về một cái gì đó như thế này ...

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

Sửa mỗi bình luận: Tôi sẽ cố gắng và làm công lý này. :)

Trong ví dụ của tôi, đó là Func<int, TKey> vì danh sách của tôi là ints. Vì vậy, tôi đang nói với GroupBy cách nhóm các mục của tôi. Func lấy một int và trả về khóa cho nhóm của tôi. Trong trường hợp này, tôi sẽ nhận được một IGrouping<int,int> (một nhóm các int được khóa bởi một int). Nếu tôi thay đổi nó thành (i => i.ToString()) ví dụ, tôi sẽ là keying nhóm của tôi bằng một chuỗi. Bạn có thể tưởng tượng một ví dụ nhỏ hơn so với keying bởi "1", "2", "3" ... có thể tôi thực hiện một chức năng trả về "một", "hai", "ba" làm chìa khóa của tôi ...

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

vì vậy, đó là một Func rằng sẽ mất một int và trả về một chuỗi, giống như ...

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

Nhưng, kể từ khi câu hỏi ban đầu được gọi là cho biết giá trị danh sách ban đầu và nó đếm, Tôi chỉ sử dụng một số nguyên để khóa nhóm số nguyên của mình để làm cho ví dụ của tôi đơn giản hơn.

+1

+1. điều này rất thanh lịch để đếm sự xuất hiện của từng yếu tố riêng biệt. –

+0

Còn danh sách.FindAll thì sao? – CodeFusionMobile

+0

FindAll trả về danh sách các phần tử từ danh sách gốc khớp với vị từ, vì vậy bạn sẽ phải thực hiện một lần cho từng yếu tố duy nhất để tìm số đếm cho phần tử đó. –

-1

vòng ngoài của bạn được lặp qua tất cả các từ trong danh sách. Nó không cần thiết và sẽ gây ra vấn đề cho bạn. Loại bỏ nó và nó sẽ hoạt động đúng.

7

Bạn có thể làm điều gì đó như thế này để đếm từ danh sách những thứ.

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

Để đếm một yếu tố duy nhất

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

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

1: Tôi đã mất một thời gian để tìm ra rằng GetMethods() chỉ là danh sách của bạn của sự vật. :) –

+0

vâng, tôi đã nghĩ về điều đó và quyết định làm cho nó dễ đọc hơn. cảm ơn, mặc dù tôi đã đọc sai câu hỏi. Nó nói để đếm "tất cả các yếu tố" .. ooops. Điều này vẫn đủ hữu ích. –

+0

@StanR. - giải pháp này hoạt động cho vấn đề của tôi. Tuy nhiên, có phương pháp nào trong danh sách mà tôi có thể đếm sự xuất hiện lớn hơn hoặc bằng từ không? Tôi đang sử dụng loại "int" thay vì "chuỗi". –

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

này được lấy từ một trong những ví dụ trong LINQPad

Các vấn đề liên quan