2010-02-17 33 views
7

Tôi đã tự dạy LINQ gần đây và áp dụng nó cho các câu đố nhỏ khác nhau. Tuy nhiên, một trong những vấn đề tôi gặp phải là LINQ-to-objects chỉ hoạt động trên các bộ sưu tập chung. Có một thủ thuật bí mật/thực hành tốt nhất để chuyển đổi một bộ sưu tập không chung chung thành một bộ sưu tập chung?Cách tốt nhất để chuyển đổi bộ sưu tập phi chung chung thành một bộ sưu tập chung là gì?

Triển khai hiện tại của tôi sao chép bộ sưu tập không chung chung vào một mảng rồi hoạt động trên đó, nhưng tôi đã tự hỏi liệu có cách nào tốt hơn không?

public static int maxSequence(string str) 
{ 
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    Match[] matchArr = new Match[matches.Count]; 
    matches.CopyTo(matchArr, 0); 
    return matchArr 
     .Select(match => match.Value.Length) 
     .OrderByDescending(len => len) 
     .First(); 
} 

Trả lời

10

Cách đơn giản nhất thường là phương pháp Cast mở rộng:

IEnumerable<Match> strongMatches = matches.Cast<Match>(); 

Lưu ý rằng đây là chậm và suối dữ liệu của nó, do đó bạn không có một "bộ sưu tập" đầy đủ như vậy - nhưng đó là một nguồn dữ liệu hoàn hảo cho các truy vấn LINQ.

Cast được tự động gọi nếu bạn chỉ định một kiểu cho biến phạm vi trong một biểu thức truy vấn:

Vì vậy, để chuyển đổi truy vấn của bạn hoàn toàn:

public static int MaxSequence(string str) 
{  
    return (from Match match in Regex.Matches(str, "H+|T+") 
      select match.Value.Length into matchLength 
      orderby matchLength descending 
      select matchLength).First(); 
} 

hoặc

public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Select(match => match.Value.Length) 
        .OrderByDescending(len => len) 
        .First(); 
} 

Trong thực tế , bạn không cần phải gọi OrderByDescending và sau đó First tại đây - bạn chỉ muốn giá trị tối đa, trong đóPhương phápgiúp bạn. Thậm chí tốt hơn, nó cho phép bạn chỉ định một chiếu từ một loại nguyên tố nguồn tới giá trị mà bạn đang cố gắng để tìm, vì vậy bạn có thể làm mà không có sự Select quá:

public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Max(match => match.Value.Length); 
} 

Nếu bạn có một bộ sưu tập trong đó có một số các yếu tố thuộc loại phù hợp nhưng một số có thể không được, bạn có thể sử dụng OfType để thay thế. Cast ném một ngoại lệ khi nó gặp một mục của loại "sai"; OfType chỉ bỏ qua nó.

+0

Cảm ơn rất nhiều! Tôi không chắc chắn làm thế nào tôi bị mất phương pháp đó trong tài liệu, nhưng đó là chính xác những gì tôi đang tìm kiếm! Cũng xin cảm ơn mẹo sử dụng Max() – guhou

0
matches.Cast<Match>(); 
1

Bạn có thể sử dụng Cast hoặc OfType trên IEnumerable để chuyển đổi. Cast sẽ ném dàn diễn viên bất hợp pháp nếu phần tử không thể truyền sang loại đã nêu trong khi OfType sẽ bỏ qua bất kỳ yếu tố nào không thể chuyển đổi được.

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