2012-08-08 8 views
48

Cho phép nói rằng tôi có danh sách một số giá trị cột đến từ bảng, làm cách nào để xóa chuỗi trống và giá trị trùng lặp. Hãy xem đoạn mã sau:cách xóa chuỗi rỗng khỏi danh sách, sau đó xóa giá trị trùng lặp khỏi danh sách

List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList(); 

Đây là những gì tôi đã được mã hóa chỉ là bây giờ nhưng nhưng mã Amiram là cách thanh lịch hơn, vì vậy tôi sẽ chọn rằng câu trả lời ở đây là làm thế nào tôi đã làm nó:

DataTable dtReportsList = someclass.GetReportsList(); 

     if (dtReportsList.Rows.Count > 0) 
     { 


      List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList(); 
      dtList.RemoveAll(x=>x == ""); 
      dtList = dtList.Distinct().ToList();   

      rcboModule.DataSource = dtList; 
      rcboModule.DataBind();    
      rcboModule.Items.Insert(0, new RadComboBoxItem("All", "All")); 


     } 
+0

Hiểu rằng RemoveAll() biến mất dtList; mỗi phần tử được loại bỏ buộc Danh sách sắp xếp lại các phần tử trong chỉ mục cao hơn trong mảng cơ bản mà nó sử dụng. Nó sẽ nhanh hơn chỉ đơn giản là bỏ qua chúng như Amiram với phương pháp Where của mình. – KeithS

Trả lời

119
dtList = dtList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList() 

Tôi cho rằng chuỗi rỗng và khoảng trắng giống như null. Nếu không, bạn có thể sử dụng IsNullOrEmpty (cho phép khoảng trắng) hoặc s != null

+2

Tôi thích mã này rất đẹp – EaterOfCode

+0

Chỉ một điều; deduping với Distinct() là tương đối kém hiệu quả vì phương thức này phải giả định trường hợp xấu nhất. – KeithS

+0

@KeithS Chúng ta biết những xác nhận nào về dữ liệu này mà 'Phân biệt 'không cho phép nó được tối ưu hóa? – Servy

7

Câu trả lời của Amiram là chính xác, nhưng khác biệt() như đã thực hiện là hoạt động N ; cho mỗi mục trong danh sách, thuật toán so sánh nó với tất cả các phần tử đã xử lý và trả về nó nếu nó là duy nhất hoặc bỏ qua nó nếu không. Chúng ta có thể làm tốt hơn.

A được sắp xếp danh sách có thể được khấu trừ theo thời gian tuyến tính; nếu phần tử hiện tại bằng phần tử trước đó, bỏ qua nó, nếu không trả về nó. Sắp xếp là NlogN, vì vậy ngay cả khi sắp xếp bộ sưu tập, chúng tôi vẫn nhận được một số lợi ích:

public static IEnumerable<T> SortAndDedupe<T>(this IEnumerable<T> input) 
{ 
    var toDedupe = input.OrderBy(x=>x); 

    T prev; 
    foreach(var element in toDedupe) 
    { 
     if(element == prev) continue; 

     yield return element; 
     prev = element;  
    } 
} 

//Usage 
dtList = dtList.Where(s => !string.IsNullOrWhitespace(s)).SortAndDedupe().ToList(); 

Điều này trả về cùng một yếu tố; chúng chỉ được sắp xếp.

+0

Tuyệt. Nếu tôi không sai, bằng cách lặp lại các phần tử bạn thực sự đang thực hiện thứ tự. Bạn có thể nghĩ ra một cách để làm cho phương pháp của bạn "lười biếng"? –

+0

Thật không may, hầu hết các loại đòi hỏi kiến ​​thức về toàn bộ bộ sưu tập được sắp xếp; yếu tố cuối cùng có thể là yếu tố đầu tiên cần được trả lại. Vì vậy, tất cả các yếu tố của đầu vào phải được đánh giá để tạo ra phần tử đầu tiên của đầu ra. Loại duy nhất tôi có thể nghĩ về điều đó có thể bị gián đoạn sau khi tìm ra phần tử tiếp theo của đầu ra của nó là một biến thể SelectionSort, và trong trường hợp đó chúng ta quay lại nơi chúng ta bắt đầu. – KeithS

+0

Bên cạnh đó, trong trường hợp của chúng tôi, kết quả của toàn bộ hoạt động là một danh sách, yêu cầu thực thi "háo hức" để bắt đầu. Nếu chúng ta muốn làm việc với nó như là một IEnumerable và trì hoãn việc thực hiện nó, bạn có thể lấy thịt của hàm và đặt nó vào một lớp Iterator ẩn mà triển khai IEnumerable. – KeithS

1

Giải pháp Amiram Korach thực sự gọn gàng. Đây là một thay thế vì lợi ích của tính linh hoạt.

var count = dtList.Count; 
// Perform a reverse tracking. 
for (var i = count - 1; i > -1; i--) 
{ 
    if (dtList[i]==string.Empty) dtList.RemoveAt(i); 
} 
// Keep only the unique list items. 
dtList = dtList.Distinct().ToList(); 
+3

Trong khi điều này sẽ làm việc, mệnh đề Where nhanh hơn vì nó không phải thay đổi bộ sưu tập đầu vào. Bạn đang giảm thiểu số lượng "thay đổi" phải được thực hiện khi xóa các phần tử khỏi danh sách, nhưng ở đâu không xóa bất kỳ thứ gì khỏi đầu vào; nó chỉ bỏ qua các yếu tố không khớp. – KeithS

+0

Cảm ơn lời giải thích. – IneedHelp