LINQ Distinct 연산자, 대소 문자 무시?


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가 실제로 대소 문자를 구분하지 않는 비교를 수행하는 데 사용되지 않는 것 같습니다.

즉, distinctListlist 와 동일한 수의 항목을 포함 합니다 . 대신에 예를 들어 "Three"와 "three"는 동일한 것으로 간주됩니다.

내가 뭔가를 놓치고 있거나 이것이 Distinct 연산자의 문제입니까?

답변:


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
당신은 단순히 이것이 필요하지 않습니다. 내 대답을 참조하십시오.
Marc Gravell

2
예, "답변 게시"를 클릭했을 때 답장이 도착했습니다.
Ash

그들은 확실히 서로 20 초 미만 이었어요. 그래도 IEqualityComparer <T>와 같은 것을 구현하는 것은 작동 방식을 이해하기 위해서만 유용한 연습입니다.
Marc Gravell

다시 한 번 감사드립니다. 누구든지 강하게 반대하지 않는 한이 답변을 게시하겠습니다.
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);
  }

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.