2016-06-17 7 views
0

문자열 배열 목록이 있습니다. 문자열 배열의 첫 번째 요소에 대해서만 검사를 수행하여 중복 및 빈 문자열을 제거하려고합니다. IEqualityComparer를 사용하여 일부 게시물을 보았습니다. 중복 제거는 전체 문자열 배열을 비교하여보다 우아하고 잠재적으로 더 효율적으로 보이게합니다. 그러나 IEqualityComparer가 나를 혼란시키기 때문에 원하지 않는 요소를 제거하기 위해 문자열 배열의 첫 번째 요소에서만이를 확인하는 데 실패했습니다. 더 우아하게 어떻게이 일을 성취 할 수 있습니까? 나의 현재 비 우아한 & 비 효율적인 작업 코드 :C# 중복 제거에만 문자열 배열의 첫 번째 요소를 확인

void method(List<string[]> contactAndNumber) 
{ 
    List<string[]> contactAndNumberSanitized = new List<string[]>(); 
    contactAndNumberSanitized.Clear(); 
    bool rem = false; 
    List<int> remList = new List<int>(); 
    for (int i = 0; i < contactAndNumber.Count; i++) 
    { 
     contactAndNumberSanitized.Add(new string[] { contactAndNumber[i][0], contactAndNumber[i][1] }); 
     for (int j = 0; j < contactAndNumberSanitized.Count; j++) 
      if (i != j) 
       if (contactAndNumber[i][0] == contactAndNumberSanitized[j][0]) 
       { 
        rem = true; 
        break; 
       } 
     if (rem || string.IsNullOrEmpty(contactAndNumber[i][0])) 
      remList.Add(i); 
     rem = false; 
    } 
    for (int i = remList.Count - 1; i >= 0; i--) 
     contactAndNumberSanitized.RemoveAt(remList[i]); 
} 

그리고이 난 단지 문자열 배열의 첫 번째 항목에 체크 할 구현하기 위해 노력 비 작동 코드 :

sealed class EqualityComparer: IEqualityComparer<string[]> 
{ 
    public bool Equals(string[] x, string[] y) 
    { 
     if (ReferenceEquals(x[0], y[0])) 
      return true; 

     if (x == null || y == null) 
      return false; 

     return x[0].SequenceEqual(y[0]); 
    } 

    public int GetHashCode(string[] obj) 
    { 
     if (obj == null) 
      return 0; 

     int hash = 17; 

     unchecked 
     { 
      foreach (string s in obj) 
       hash = hash*23 + ((s == null) ? 0 : s.GetHashCode()); 
     } 

     return hash; 
    } 
} 

작성자

var result = list.Distinct(new EqualityComparer()); 

답변

3

귀하의 코드를 크게 단순화 할 수있다 :

몇 가지 방법에 따라 본를 호출

이것은 고유성을 결정하기 위해 각 배열의 첫 번째 요소를 사용하여 고유 한 배열을 제공합니다.

그러나 고유성을 결정하기 위해 배열의 첫 번째 요소를 사용하고 있으므로 빈 세트가 { null }과 동일한 것으로 보이는 가장자리의 경우가 있습니다. 당신이 목록 <T>와 협력하고 있기 때문에 당신이 빈 세트를 처리하는 방법에 따라 입력을 필터링하는 코드를 수정해야하거나 GroupBy

+0

나는 한 줄의 해결책이기 때문에 대답으로 받아들이고 있습니다. 메이트 - 최고 녀석! =)이 LINQ 쿼리 내에서 빈 문자열 키가있는 배열을 제거 할 수 있습니까? –

+1

@BarryGuvenkaya 물론, 그룹 앞에 필터를 추가하십시오. 예를 들면 :'input.Where (a =>! string.IsNullOrEmpty (a.FirstOrDefault())) .GroupBy (...'). 빈 배열을 모두 지우고 첫 번째 (그리고/또는 단지) ​​요소 – Rob

0

을 변경할 수 있습니다, 당신은에서 removeAll의 방법을 사용할 수 있습니다.

편집 : 원본 답변이 작동하지 않을 수 있습니다. 아래의 개정.

편집 2 : (원본을 떠나지 않고) 모든 중복을 제거하려면 사실,이 사용

var duplicates = data.Where(x => x == null || string.IsNullOrEmpty(x[0]) || data.Where(y => y != null).Count(y => y[0] == x[0]) > 1).ToList(); 
data.RemoveAll(x => duplicates.Contains(x)); 

그러나 당신은 (중복 세트의 마지막를 마칠 경우 예를 들어, 마지막 "A"세 세트), 그럼 당신은 내 원래의 대답을 사용할 수 있습니다 :

data.RemoveAll(x => x == null || string.IsNullOrEmpty(x[0]) || data.Where(y => y != null).Count(y => y[0] == x[0]) > 1); 
+0

불행히도 이것은 나를 위해 작동하지 않았다. 어쨌든 빠른 답변 주셔서 감사합니다. –