it-swarm.com.de

LINQ eindeutiger Operator, Fall ignorieren?

Anhand des folgenden einfachen Beispiels:

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

Es scheint, dass der CaseInsensitiveComparer nicht für einen Vergleich verwendet wird, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird. 

Mit anderen Worten enthält distinctList die gleiche Anzahl von Elementen wie list . Stattdessen würde ich beispielsweise erwarten, dass "Drei" und "Drei" als gleichwertig betrachtet werden.

Fehlt mir etwas oder ist dies ein Problem mit dem Operator Distinct?

81
Ash

StringComparer macht, was Sie brauchen:

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

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

(oder invariant/ordinal/etc abhängig von den Daten, die Sie vergleichen)

198
Marc Gravell

[Siehe Antwort von Marc Gravells, wenn Sie den präzisesten Ansatz wünschen]

Nach einiger Untersuchung und gutem Feedback von Bradley Grainger habe ich den folgenden IEqualityComparer implementiert. Es unterstützt eine Distinct () - Anweisung, bei der die Groß-/Kleinschreibung nicht beachtet wird (übergeben Sie einfach eine Instanz davon an den Distinct-Operator):

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
}
3
Ash

Hier ist eine wesentlich einfachere Version.

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
Morrison

 ## 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 wird sein

   USA 
   INDIA
   UK
0
Javed Ahmad