LINQ ตัวดำเนินการที่แตกต่างไม่สนใจตัวพิมพ์หรือไม่


100

ยกตัวอย่างง่ายๆดังต่อไปนี้:

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

ดูเหมือนว่า CaseInsensitiveComparer ไม่ได้ถูกใช้เพื่อทำการเปรียบเทียบแบบไม่คำนึงถึงตัวพิมพ์

ในคำอื่น ๆdistinctList มีหมายเลขเดียวกันของรายการเป็นรายการ แต่ฉันจะคาดหวังเช่น "สาม" และ "สาม" จะถือว่าเท่ากัน

ฉันขาดอะไรไปหรือนี่เป็นปัญหากับตัวดำเนินการที่แตกต่างกัน

คำตอบ:


240

StringComparer ทำในสิ่งที่คุณต้องการ:

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

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

(หรือไม่แปรผัน / ลำดับ / ฯลฯ ขึ้นอยู่กับข้อมูลที่คุณกำลังเปรียบเทียบ)


5

[ดูคำตอบของ Marc Gravells หากคุณต้องการแนวทางที่กระชับที่สุด]

หลังจากการตรวจสอบและข้อเสนอแนะที่ดีจาก Bradley Grainger ฉันได้ใช้ IEqualityComparer ดังต่อไปนี้ มันรองรับคำสั่ง Distinct ที่ไม่ไวต่อตัวพิมพ์เล็กและใหญ่ (เพียงแค่ส่งตัวอย่างของสิ่งนี้ไปยังตัวดำเนินการที่แตกต่างกัน):

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
}

6
คุณไม่จำเป็นต้องใช้สิ่งนี้ ดูคำตอบของฉัน
Marc Gravell

2
ใช่คำตอบของคุณมาถึงขณะที่ฉันคลิก "โพสต์คำตอบของคุณ"
เถ้า

พวกเขาอยู่ด้วยกัน <20 วินาทีฉันจำได้ ถึงกระนั้นการใช้บางอย่างเช่น IEqualityComparer <T> ยังคงเป็นแบบฝึกหัดที่มีประโยชน์หากเพียงเพื่อทำความเข้าใจว่ามันทำงานอย่างไร ...
Marc Gravell

ขอขอบคุณอีกครั้งฉันจะปล่อยให้คำตอบนี้เป็นจริงเว้นแต่จะมีใครคัดค้านอย่างรุนแรง
เถ้า

ตัวอย่างนี้ล้มเหลวเมื่อเริ่มต้นสำหรับวัฒนธรรม tr-TR หากวัฒนธรรมปัจจุบันเป็น en-US เนื่องจาก GetHashCode จะรายงานค่าที่แตกต่างกันสำหรับ I (U + 0049) และı (U + 0131) ในขณะที่ Equals จะถือว่าค่าเหล่านี้เท่ากัน
Bradley Grainger

1

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

OutPut จะเป็น

   USA 
   INDIA
   UK

3
โปรดหลีกเลี่ยงการโพสต์ข้อมูลโค้ดโดยไม่มีคำอธิบาย แก้ไขคำตอบของคุณและเพิ่มเนื้อหาเข้าไป ขอบคุณ.
Clijsters

0

นี่คือเวอร์ชันที่ง่ายกว่ามาก

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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.