LINQ唯一运算符,忽略大小写吗?


96

给出以下简单示例:

    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 包含与list相同数量的项目。相反,我希望例如将“三个”和“三个”视为相等。

我是否缺少某些东西,或者Distinct运算符是否有问题?

Answers:


233

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()语句(只需将其实例传递给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
您根本不需要这个。查看我的回复。
马克·格拉韦尔

2
是的,就像我单击“发布您的答案”一样,您的答复已经到达。
灰烬

我记得,他们彼此之间的时间肯定少于20秒。尽管如此,实现IEqualityComparer <T>之类的东西仍然是一个有用的练习,即使只是为了了解它是如何工作的……
Marc Gravell

再次感谢,除非有人强烈反对,否则我将继续回答这个问题。
Ash Ash

如果当前区域性是en-US,则在为tr-TR区域性初始化时,此样本将失败,因为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);
  }

输出将是

   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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.