고유 한 문자열의 효율적인 목록 C #


86

중복을 무시하고 문자열 목록을 저장하는 가장 효율적인 방법은 무엇입니까? dict [str] = false; 키를 통해 목록으로 열거합니다. 그게 좋은 해결책인가요?

답변:


111

.NET 3.5를 사용하는 경우 HashSet 이 작동합니다.

HashSet <(Of <(T>)>) 클래스는 고성능 집합 작업을 제공합니다. 집합은 중복 요소를 포함하지 않고 요소가 특정 순서가 아닌 컬렉션입니다.


5
그러나 HashSet항목의 순서를 잃을 것입니다. A가 List제공 하는 기능 입니다.
aggsol

4
추가 : 편리한 정렬 HashSet 인 SortedSet <T>도 있습니다.
WhoIsRich 2015

또한 HashSet은 indice를 통해 액세스 할 수 없으며 List와 반대되는 열거자를 통해서만 액세스 할 수 있습니다.
Andrew

23

이런 식으로 할 수 있습니다.

var hash = new HashSet<string>();
var collectionWithDup = new []{"one","one","two","one","two","zero"}; 

// No need to check for duplicates as the Add method
// will only add it if it doesn't exist already
foreach (var str in collectionWithDup)
    hash.Add(str);   

33
HashSet으로 포함 검사가 필요하지 않습니다. Add 메서드를 직접 호출하면 항목이 이미 존재하는지 여부에 따라 true 또는 false가 반환됩니다.
LukeH

1
중복 포함에 대한 호출을 제거하려면 응답을 편집해야합니다. 위의 예제가 작동하는 데 필요한 모든 것 : var collectionWithDup = new [] { "one", "one", "two", "one", "two", "zero"}; var uniqueValues ​​= new HashSet <string> (collectionWithDup);
user3285954 aug

14

이것이 좋은 대답으로 간주되는지 확실하지 않지만 삽입 순서를 유지하는 고유 한 집합이 필요하면 HashSet과 List를 나란히 사용했습니다. 이 경우 세트에 추가 할 때마다 다음을 수행하십시오.

if(hashSet.Add(item))
    orderList.Add(item);

항목을 제거 할 때는 두 항목 모두에서 제거해야합니다. 따라서 다른 항목이 목록에 추가되지 않았 음을 확신 할 수있는 한 삽입 순서가 지정된 고유 세트를 갖게됩니다!


10

Linq를 다음과 같이 사용할 수도 있습니다.

using System.Linq;

var items = new List<string>() { "one", "one", "two", "one", "two", "zero" };

List<string> distinctItems = items.Distinct().ToList();

8

HashSet을 사용하고 .Contains ()를 확인할 필요가 없습니다. 목록에 항목을 추가하기 만하면 중복되는 항목이 추가되지 않습니다.

   HashSet<int> uniqueList = new HashSet<int>();
   uniqueList.Add(1); // List has values 1
   uniqueList.Add(2);  // List has values 1,2
   uniqueList.Add(1);  // List has values 1,2
   Console.WriteLine(uniqueList.Count); // it will return 2

2

이것은 시스템 네임 스페이스의 일부가 아니지만 NHibernate와 함께 http://www.codeproject.com/KB/recipes/sets.aspx 의 Iesi.Collections를 사용했습니다 . 정렬 된 세트, 사전 세트 등과 함께 해시 된 세트를 지원합니다. NHibernate와 함께 사용 되었기 때문에 광범위하고 매우 안정적으로 사용되었습니다. .Net 3.5도 필요하지 않습니다.


2

다음은 HashSet.

var items = new List<string>() { "one", "one", "two", "one", "two", "zero" };
var uniqueItems = items.Where((item, index) => items.IndexOf(item) == index);

이 스레드에서 채택되었습니다 : javascript-배열의 고유 값

테스트:

using FluentAssertions;

uniqueItems.Count().Should().Be(3);
uniqueItems.Should().BeEquivalentTo("one", "two", "zero");

성능에 대한 테스트 List, HashSetSortedSet. 1 백만 회 반복 :

List: 564 ms
HashSet: 487 ms
SortedSet: 1932 ms

테스트 소스 코드 (요점)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.