2013-04-24 2 views
18

개체 목록에서 중복을 확인하는 정말 빠른 방법을 찾고 있습니다.개체 목록에서 중복 검사 C#

단순히 목록을 반복하고 수동 비교를 그런 식으로 일을 생각했다,하지만 난 LINQ는 더 우아한 솔루션을 제공 할 수 있다고 생각 ...

나는 객체 ...

한다고 가정해야
public class dupeCheckee 
{ 
    public string checkThis { get; set; } 
    public string checkThat { get; set; } 

    dupeCheckee(string val, string val2) 
    { 
     checkThis = val; 
     checkThat = val2; 
    } 
} 

은 내가

List<dupeCheckee> dupList = new List<dupeCheckee>(); 
dupList.Add(new dupeCheckee("test1", "value1")); 
dupList.Add(new dupeCheckee("test2", "value1")); 
dupList.Add(new dupeCheckee("test3", "value1")); 
dupList.Add(new dupeCheckee("test1", "value1"));//dupe 
dupList.Add(new dupeCheckee("test2", "value1"));//dupe... 
dupList.Add(new dupeCheckee("test4", "value1")); 
dupList.Add(new dupeCheckee("test5", "value1")); 
dupList.Add(new dupeCheckee("test1", "value2"));//not dupe 

내가 그 목록에 속는을 찾을 필요가 해당 개체의 목록을 가지고있다. 찾으면 일부 논리를 추가로 제거해야합니다. 반드시 제거하지 않아도됩니다.

내가 LINQ를 사용하면 내 GROUPBY가 예외를 던지는 방법을 몇 가지 ...

'System.Collections.Generic.List<dupeCheckee>' does not contain a definition for 'GroupBy' and no extension method 'GroupBy' accepting a first argument of type 'System.Collections.Generic.List<dupeCheckee>' could be found (are you missing a using directive or an assembly reference?) 
내가 라이브러리를 놓치고 내게 말하고있다

. 나는 어느 것을 생각하는지 어려움을 겪고있다.

한번 생각해 보면 본질적으로 그 두 가지 조건을 확인하는 방법은 무엇입니까? IE checkThis와 checkThat 모두 두 번 이상 발생합니까?

UPDATE :이 확실히 더 나은 경우

test.Count != test.Select(c => new { c.checkThat, c.checkThis }).Distinct().Count() 

내가 확실하지 오전 ...

이 내가 빠른 연구를 수행 한 후 함께 제공되는 LINQ 쿼리입니다 해낸 이 대답보다 ...

나는 첫 번째 문장을 if else 절에 넣을 수 있음을 알고 있습니다. 나는 또한 빠른 테스트를했다. 중복 목록은 내가 0을 기대하고 있었을 때 1을 되 돌렸지 만, 내가 사용한 세트 중 하나에서 중복 된 사실을 정확하게 호출했다. ...

다른 방법론은 내가 기대했던대로 정확하게 수행한다.

List<DupeCheckee> test = new List<DupeCheckee>{ 
    new DupeCheckee("test0", "test1"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test1", "test2"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test2", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test0", "test5"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test1", "test6"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test2", "test7"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test3", "test8"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test0", "test5"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test1", "test1"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test2", "test2"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test4", "test4"),//{ checkThis = "test", checkThat = "test1"} 

}; 

없음 속는 ...

 List<DupeCheckee> test2 = new List<DupeCheckee>{ 
    new DupeCheckee("test0", "test1"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test1", "test2"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test2", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test4", "test5"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test5", "test6"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test6", "test7"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test7", "test8"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test8", "test5"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test9", "test1"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test2", "test2"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"} 
    new DupeCheckee("test4", "test4"),//{ checkThis = "test", checkThat = "test1"} 

}; 
+1

'System.Linq; '를 cs 파일 맨 위에 추가하면'GroupBy'가 작동합니다. –

+0

예. 그냥 내가 그것을 놓친 걸 알았어. 감사. – SoftwareSavant

+2

Erm 더플은 속량을 가지고 있지 않습니다. test3, test3 –

답변

30

System.Linq (예 :전화를 중복에 대한 시험은 다음 심지어

var hasDupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat}) 
        .Where(x => x.Skip(1).Any()).Any(); 

또는 것 using System.Linq) 다음

당신은

var dupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat}) 
        .Where(x => x.Skip(1).Any()); 

이 모든 중복

당신에게 그룹을 줄 것이다 할 수 ToList() 또는 ToArray() 결과의 계산을 강제로 수행 한 다음 속임수를 확인하고 검토 할 수 있습니다. 예를 들어

.. 당신에게 그룹별로 각 항목은 속성 속성 index 및 항목에 원래의 인덱스를 저장하는 그룹을 제공 또는

var dupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat}) 
        .Where(x => x.Skip(1).Any()).ToArray(); 
if (dupes.Any()) { 
    foreach (var dupeList in dupes) { 
    Console.WriteLine(string.Format("checkThis={0},checkThat={1} has {2} duplicates", 
         duplist.Key.checkThis, 
         duplist.Key.checkThat, 
         duplist.Count() - 1)); 
    } 

} 

var dupes = dupList.Select((x, i) => new { index = i, value = x}) 
        .GroupBy(x => new {x.value.checkThis, x.value.checkThat}) 
        .Where(x => x.Skip(1).Any()); 

value

+0

나는 정말 그 물건에 사기가 전혀 없는지보고 싶다. 여러 개의 'List '을 모두 가지고있는 것이 좋을 것입니다 ... 사용자가 나중에 제거하려고하면 좋을 것입니다. 그러나 목록에 중복 목록이 있는지 확인하려고합니다. – SoftwareSavant

+0

@DmainEvent 그게 뭐야? 중복성이 있는지 확인하려면 'dupes.Any()'에 중복이 있는지 확인하십시오 –

+0

내 솔루션을 살펴보고 내 솔루션에 결함이 있는지 확인하십시오. 나는 너의 것과 내 것을 모두 시험해 보았다. 내 것은 괜찮아 보인다. 너의 것에 대해서는 확신하지 못한다. – SoftwareSavant

0

는 LINQ, 예를 들어,와 선택 구별를 수행 여기

속는 내가 이것을 테스트하는 데 사용하는 데이터 세트는 ....입니다 How can I do SELECT UNIQUE with LINQ?

그런 다음 뚜렷한 결과의 개수를 뚜렷하지 않은 결과와 비교하십시오. 목록에 두 배가 있으면 부울을 제공합니다.

또한 고유 한 키임을 보장하는 사전을 사용해 볼 수도 있습니다.

+0

속물로 무엇인가하고 싶다면'GroupBy'가 더 나은 방법입니다. –

+0

@ 대니얼 그래서 나는 그것을 upvote 수 있으며 사용자가 답변으로 표시 할 수있는 답변으로 게시하십시오! – MatthewMartin

1

나는 이것이 당신이 찾고있는 것이라고 생각한다 :

List<dupeChecke> duplicates = dupeList.GroupBy(x => x) 
            .SelectMany(g => g.Skip(1)); 
+1

'dupeCheckee '에 대한 equals 체크가 인스턴스에 대해 equal 여기서'checkThis'와'checkThat'는 동일합니다. –

+0

@BobVale : 그가 더 이상 그것을 무너 뜨리고 싶지 않았다는 것을 눈치 채지 못했습니다! 귀하의 의견을 upvoted. –

0

메모리 개체의 경우 항상 필자는 LINQ 메서드를 사용하여 솔루션에 비교자를 추가합니다.

public class dupeCheckee 
{ 
    public string checkThis { get; set; } 
    public string checkThat { get; set; } 

    dupeCheckee(string val, string val2) 
    { 
     checkThis = val; 
     checkThat = val2; 
    } 

    public class Comparer : IEqualityComparer<dupeCheckee> 
    { 
     public bool Equals(dupeCheckee x, dupeCheckee y) 
     { 
      if (x == null || y == null) 
       return false; 

      return x.CheckThis == y.CheckThis && x.CheckThat == y.CheckThat; 
     } 

     public int GetHashCode(dupeCheckee obj) 
     { 
      if (obj == null) 
       return 0; 

      return (obj.CheckThis == null ? 0 : obj.CheckThis.GetHashCode())^
       (obj.CheckThat == null ? 0 : obj.CheckThat.GetHashCode()); 
     } 
    } 
} 

이제 우리는 전혀 중복이있을 때 내가 아는이를 사용하여 좋아

List<dupeCheckee> dupList = new List<dupeCheckee>(); 
dupList.Add(new dupeCheckee("test1", "value1")); 
dupList.Add(new dupeCheckee("test2", "value1")); 
dupList.Add(new dupeCheckee("test3", "value1")); 
dupList.Add(new dupeCheckee("test1", "value1"));//dupe 
dupList.Add(new dupeCheckee("test2", "value1"));//dupe... 
dupList.Add(new dupeCheckee("test4", "value1")); 
dupList.Add(new dupeCheckee("test5", "value1")); 
dupList.Add(new dupeCheckee("test1", "value2"));//not dupe 

var distinct = dupList.Distinct(dupeCheckee.Comparer); 
+0

별개의 목록을 얻고 있지만 목록에 중복 목록이 있는지 파악하려고합니다. – SoftwareSavant

0

호출 할 수 있습니다. 문자열이 있고 중복 문자가 있는지 알고 싶다고합시다. 이것이 내가 사용하는 것입니다.

string text = "this is some text"; 

var hasDupes = text.GroupBy(x => x).Any(grp => grp.Count() > 1); 

중복 수가 얼마나되는지 알고 싶다면 이것을 사용하십시오. 편지의 3

총 I : 2

총 편지의

var totalDupeItems = text.GroupBy(x => x).Count(grp => grp.Count() > 1); 

그래서 예를 들어, 편지 t의

총 ...이있다 "이 일부 텍스트가" : 편지 전자의 3

총 : 2

그래서 변수 totalDupeItems 4와 동일합니다. 4 가지 종류의 중복이 있습니다.

사기가 무엇이든간에 사기 항목의 총량을 얻고 싶다면 이것을 사용하십시오.

var totalDupes = letters.GroupBy(x => x).Where(grp => grp.Count() > 1).Sum(grp => grp.Count()); 

그래서 totalDupes 변수는 10입니다.이 값은 합쳐진 각 중복 유형의 총 중복 항목입니다.

5

작동 솔루션의 거대한 양의가 있었다, 그러나 나는 다음 솔루션은 모든 위, 이해하기 더 투명하고 쉽게 될 것이라고 생각 : 중복이 예외를 throw 발생

var hasDuplicatedEntries = ListWithPossibleDuplicates 
            .GroupBy(YourGroupingExpression) 
            .Any(e => e.Count() > 1); 
if(hasDuplicatedKeys) 
{ 
    // Do what ever you want in case when list contains duplicates 
} 
0

합니다. 사전은 키를 자체 검사합니다. 이것은 가장 쉬운 방법입니다.

try 
{ 
    dupList.ToDictionary(a=>new {a.checkThis,a.checkThat}); 
} 
catch{ 
//message: list items is not uniqe 
}