2008-11-12 10 views
73

Với ví dụ đơn giản sau:LINQ Toán tử riêng biệt, bỏ qua trường hợp?

List<string> list = new List<string>() { "One", "Two", "Three", "three", "Four", "Five" }; 

    CaseInsensitiveComparer ignoreCaseComparer = new CaseInsensitiveComparer(); 

    var distinctList = list.Distinct(ignoreCaseComparer as IEqualityComparer<string>).ToList(); 

Dường như CaseInsensitiveComparer không thực sự được sử dụng để làm một so sánh case-insensitive.

Nói cách khác distinctList chứa cùng một số mục như danh sách. Thay vào đó tôi mong chờ, ví dụ, "Ba" và "ba" được coi là bằng nhau.

Tôi có thiếu gì đó hoặc đây có phải là vấn đề với toán tử Distinct không?

Trả lời

182

StringComparer làm những gì bạn cần:

List<string> list = new List<string>() { 
    "One", "Two", "Three", "three", "Four", "Five" }; 

var distinctList = list.Distinct(
    StringComparer.CurrentCultureIgnoreCase).ToList(); 

(hoặc bất biến/ordinal/etc tùy thuộc vào dữ liệu bạn đang so sánh)

+0

Đó là tuyệt vời, cảm ơn. – Ash

3

[Xem Marc Gravells câu trả lời nếu bạn muốn phương pháp ngắn gọn nhất]

Sau một số điều tra và phản hồi tốt từ Bradley Grainger, tôi đã triển khai IEqualityComparer sau đây. Nó suports một trường hợp không nhạy cảm riêng biệt() statement (chỉ cần vượt qua một thể hiện của này để các nhà điều hành riêng biệt):

class IgnoreCaseComparer : IEqualityComparer<string> 
{ 
    public CaseInsensitiveComparer myComparer; 

    public IgnoreCaseComparer() 
    { 
     myComparer = CaseInsensitiveComparer.DefaultInvariant; 
    } 

    public IgnoreCaseComparer(CultureInfo myCulture) 
    { 
     myComparer = new CaseInsensitiveComparer(myCulture); 
    } 

    #region IEqualityComparer<string> Members 

    public bool Equals(string x, string y) 
    { 
     if (myComparer.Compare(x, y) == 0) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public int GetHashCode(string obj) 
    { 
     return obj.ToLower().GetHashCode(); 
    } 

    #endregion 
} 
+5

Bạn chỉ đơn giản là không cần điều này. Xem trả lời của tôi. –

+2

Có, thư trả lời của bạn đã đến ngay khi tôi nhấp vào "Đăng câu trả lời của bạn". – Ash

+0

Họ chắc chắn với <20 giây của nhau, tôi nhớ lại. Tuy nhiên, thực hiện một cái gì đó như IEqualityComparer vẫn là một bài tập hữu ích, nếu chỉ cho sự hiểu biết làm thế nào nó hoạt động ... –

0

Đây là một phiên bản đơn giản hơn nhiều.

List<string> list = new List<string>() { "One", "Two", "Three", "three", "Four", "Five" }; 

var z = (from x in list select new { item = x.ToLower()}).Distinct(); 

z.Dump(); 
0

## Distinct Operator(Ignoring Case) ## 
    string[] countries = {"USA","usa","INDIA","UK","UK" }; 

    var result = countries.Distinct(StringComparer.OrdinalIgnoreCase); 

    foreach (var v in result) 
    { 
    Console.WriteLine(v); 
    } 

đầu ra sẽ được

USA 
    INDIA 
    UK 
+3

Vui lòng tránh đăng đoạn mã mà không cần giải thích. Chỉnh sửa câu trả lời của bạn và thêm nội dung vào câu trả lời. Cảm ơn. – Clijsters