Development Tip

목록의 모든 값이 고유한지 테스트

yourdevel 2020. 10. 15. 21:50
반응형

목록의 모든 값이 고유한지 테스트


작은 바이트 목록이 있고 모두 다른 값인지 테스트하고 싶습니다. 예를 들어 다음과 같습니다.

List<byte> theList = new List<byte> { 1,4,3,6,1 };

모든 값이 구별되는지 확인하는 가장 좋은 방법은 무엇입니까?


bool isUnique = theList.Distinct().Count() == theList.Count();

여기에 Enumerable.Distinct+ 보다 더 효율적인 또 다른 접근법이 있습니다 Enumerable.Count(시퀀스가 컬렉션 유형이 아닌 경우 더욱 그렇습니다). 그것은 사용하는 HashSet<T>중복을 제거하는이 조회에서 매우 효율적이며 카운트 속성이 있습니다 :

var distinctBytes = new HashSet<byte>(theList);
bool allDifferent = distinctBytes.Count == theList.Count;

또는 다른-더 미묘하고 효율적인 접근법 :

var diffChecker = new HashSet<byte>();
bool allDifferent = theList.All(diffChecker.Add);

HashSet<T>.Addfalse요소가 이미에 있었기 때문에 추가 할 수없는 경우를 반환 합니다 HashSet. Enumerable.All첫 번째 "거짓"에서 중지합니다.


좋습니다. 여기에 표준 .Net을 사용하는 가장 효율적인 방법이 있습니다.

using System;
using System.Collections.Generic;

public static class Extension
{
    public static bool HasDuplicate<T>(
        this IEnumerable<T> source,
        out T firstDuplicate)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        var checkBuffer = new HashSet<T>();
        foreach (var t in source)
        {
            if (checkBuffer.Add(t))
            {
                continue;
            }

            firstDuplicate = t;
            return true;
        }

        firstDuplicate = default(T);
        return false;
    }
}

본질적으로, 당신이 원하는 것은 첫 번째 복제본을 찾는 것이라면 전체 시퀀스를 두 번 열거하는 요점은 무엇입니까?

빈 단일 요소 시퀀스를 특수 케이스로 처리하여이를 더 최적화 할 수 있지만 최소한의 이득으로 가독성 / 유지 보수 가능성이 떨어집니다.


많은 해결책이 있습니다.

그리고 "juergen d"와 "Tim Schmelter"로 LINQ를 사용한 더 아름다운 것들은 의심 할 여지가 없습니다.

But, if you bare "Complexity" and speed, the best solution will be to implement it by yourself. One of the solution will be, to create an array of N size (for byte it's 256). And loop the array, and on every iteration will test the matching number index if the value is 1 if it does, that means i already increment the array index and therefore the array isn't distinct otherwise i will increment the array cell and continue checking.


And another solution, if you want to find duplicated values.

var values = new [] { 9, 7, 2, 6, 7, 3, 8, 2 };

var sorted = values.ToList();
sorted.Sort();
for (var index = 1; index < sorted.Count; index++)
{
    var previous = sorted[index - 1];
    var current = sorted[index];
    if (current == previous)
        Console.WriteLine(string.Format("duplicated value: {0}", current));
}

Output:

duplicated value: 2
duplicated value: 7

http://rextester.com/SIDG48202


The similar logic to Distinct using GroupBy:

var isUnique = theList.GroupBy(i => i).Count() == theList.Count;

참고URL : https://stackoverflow.com/questions/18303897/test-if-all-values-in-a-list-are-unique

반응형