2008-08-23 24 views
8

Cách tốt nhất để tìm một thứ gì đó trong danh sách là gì? Tôi biết LINQ có một số thủ thuật tốt đẹp, nhưng chúng ta hãy cũng nhận được gợi ý cho C# 2.0. Cho phép có được cấu trúc lại tốt nhất cho mẫu mã phổ biến này.Cách sạch nhất để tìm một trận đấu trong danh sách

Hiện nay tôi sử dụng mã như thế này:

// mObjList is a List<MyObject> 
MyObject match = null; 
foreach (MyObject mo in mObjList) 
{ 
    if (Criteria(mo)) 
    { 
     match = mo; 
     break; 
    } 
} 

hoặc

// mObjList is a List<MyObject> 
bool foundIt = false; 
foreach (MyObject mo in mObjList) 
{ 
    if (Criteria(mo)) 
    { 
     foundIt = true; 
     break; 
    } 
} 

Trả lời

14

@ Konrad: Vậy làm thế nào để bạn sử dụng? Giả sử tôi muốn khớp mo.ID với magicNumber.

Trong C# 2.0, bạn có muốn viết:

result = mObjList.Find(delegate(int x) { return x.ID == magicNumber; }); 

3,0 biết lambdas:

result = mObjList.Find(x => x.ID == magicNumber); 
1

Đặt mã trong một phương pháp và giúp bạn tiết kiệm tạm thời và một break (và bạn tái chế mã, như một phần thưởng) :

T Find<T>(IEnumerable<T> items, Predicate<T> p) { 
    foreach (T item in items) 
     if (p(item)) 
      return item; 

    return null; 
} 

… nhưng tất nhiên phương thức này đã tồn tại cho Danh sách, ngay cả trong .NET 2.0.

4

Sử dụng một biểu thức Lambda:

List<MyObject> list = new List<MyObject>(); 

// populate the list with objects.. 

return list.Find(o => o.Id == myCriteria); 
1

Rõ ràng việc thực hiện hit của vô danh đại biểu là khá đáng kể.

mã kiểm tra:

static void Main(string[] args) 
    { 
     for (int kk = 0; kk < 10; kk++) 
     { 
      List<int> tmp = new List<int>(); 
      for (int i = 0; i < 100; i++) 
       tmp.Add(i); 
      int sum = 0; 
      long start = DateTime.Now.Ticks; 
      for (int i = 0; i < 1000000; i++) 
       sum += tmp.Find(delegate(int x) { return x == 3; }); 
      Console.WriteLine("Anonymous delegates: " + (DateTime.Now.Ticks - start)); 


      start = DateTime.Now.Ticks; 
      sum = 0; 
      for (int i = 0; i < 1000000; i++) 
      { 
       int match = 0; 
       for (int j = 0; j < tmp.Count; j++) 
       { 
        if (tmp[j] == 3) 
        { 
         match = tmp[j]; 
         break; 
        } 
       } 
       sum += match; 
      } 
      Console.WriteLine("Classic C++ Style: " + (DateTime.Now.Ticks - start)); 
      Console.WriteLine(); 
     } 
    } 

Kết quả:

Anonymous delegates: 710000 
Classic C++ Style: 340000 

Anonymous delegates: 630000 
Classic C++ Style: 320000 

Anonymous delegates: 630000 
Classic C++ Style: 330000 

Anonymous delegates: 630000 
Classic C++ Style: 320000 

Anonymous delegates: 610000 
Classic C++ Style: 340000 

Anonymous delegates: 630000 
Classic C++ Style: 330000 

Anonymous delegates: 650000 
Classic C++ Style: 330000 

Anonymous delegates: 620000 
Classic C++ Style: 330000 

Anonymous delegates: 620000 
Classic C++ Style: 340000 

Anonymous delegates: 620000 
Classic C++ Style: 400000 

Trong mọi trường hợp, sử dụng các đại biểu vô danh là chậm hơn so với các cách khác khoảng 100%.

+1

Không, hiệu suất đạt được ở đây không sử dụng đại biểu. Thuật toán của bạn hoạt động cơ bản khác nhau, phương thức đầu tiên có thời gian chạy tiệm cận O (n^2) trong khi phương thức thứ hai có thời gian chạy O (n). Điều này không liên quan gì đến các đại biểu mà là sử dụng chức năng 'Find' trong ngữ cảnh này. –

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