사전의 요소 순서


107

내 질문은 Dictionary 요소를 열거하는 것입니다.

// Dictionary definition
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>();

// add values using add

_Dictionary.Add("orange", "1");
_Dictionary.Add("apple", "4");
_Dictionary.Add("cucumber", "6");

// add values using []

_Dictionary["banana"] = 7;
_Dictionary["pineapple"] = 7;

// Now lets see how elements are returned by IEnumerator
foreach (KeyValuePair<string, string> kvp in _Dictionary)
{
  Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value));
}

요소는 어떤 순서로 열거됩니까? 주문을 알파벳순으로 강제 할 수 있습니까?


답변:


125

사전에있는 요소의 순서는 결정적이지 않습니다. 순서 개념은 단순히 해시 테이블에 대해 정의되지 않습니다. 따라서 요소가 사전에 추가 된 것과 동일한 순서로 열거하는 데 의존하지 마십시오. 그것은 보장되지 않습니다.

문서에서 인용 :

열거를 위해 사전의 각 항목 KeyValuePair<TKey, TValue>은 값과 키를 나타내는 구조 로 처리됩니다 . 항목이 반환되는 순서는 정의되지 않았습니다.


1
그러나 OrderedDictionary가 있습니다.
Peter Mortensen

28

요소를 정렬하려면 OrderedDictionary를 사용하십시오 . 일반적인 hastable / dictionary는 저장소 레이아웃의 일부 의미에서만 주문됩니다.


10
OrderedDictionary는 대부분의 경우 잘못되었습니다. 키나 값으로 정렬되지 않고 내부 인덱스로 정렬됩니다. SortedDictionary는 사용자가 조작 할 수있는 방식으로 정렬 된 것입니다 (기본 키)
Offler

2
질문은 알파벳 순서로 정렬하는 것에 대해 묻는 것입니다 (질문자가 키에 대해 이야기하고 있다고 가정). 문서를 올바르게 이해하면 정렬 된 사전은 삽입 된 순서대로 요소를 뱉어냅니다. 즉, 알파벳순이 아니라 내부 색인을 사용합니다. SortedDictionary는 아마도 사용자의 질문에 가장 적합 할 것입니다.
mattpm

28

항상 사용할 수 있습니다 SortedDictionary. 비교자가 지정되지 않은 경우 사전은 기본적으로 Key별로 정렬됩니다.

OrderedDictionary문서에 따르면 다음과 같이 원하는 것을 사용하는 것에 대해 회의적 입니다.

OrderedDictionary의 요소는 SortedDictionary 클래스의 요소와 달리 키를 기준으로 정렬되지 않습니다.


SortedDictionary<K,V>이진 검색 트리로 구현되어 해시 테이블 기반 .NET과 비교하여 작업에 다른 시간 및 공간 복잡성을 제공 한다는 점에 유의하는 것이 중요합니다 Dictionary<K,V>. 사용자가 O(1)삽입 / 삭제 해시 테이블 구조 가 필요하고 키 순서로 요소를 반복하려는 경우 dict.Keys.OrderBy( k => k ).Select( k => dict[k] )대신 ( O(n)공간과 O( n log n )시간 의 희생 으로) OrderBy()내부 목록에서 전체 키 컬렉션을 버퍼링해야합니다. ).
Dai

12

항목은 해시 코드와 항목이 추가 된 순서에 따라 사전에 물리적으로 저장되는 순서대로 반환됩니다. 따라서 순서는 무작위로 보일 것이며 구현이 변경됨에 따라 동일하게 유지되는 순서에 의존해서는 안됩니다.

항목을 열거 할 때 주문할 수 있습니다.

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) {
  ...
}

프레임 워크 2.0에서는 항목을 정렬하기 위해 먼저 목록에 항목을 넣어야합니다.

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary);
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); });
foreach (KeyValuePair<string,string> kvp in items) {
  ...
}

11

OrderedDictionary의 경우 :

 var _OrderedDictionary = new System.Collections.Specialized.OrderedDictionary();

_OrderedDictionary.Add("testKey1", "testValue1");
_OrderedDictionary.Add("testKey2", "testValue2");
_OrderedDictionary.Add("testKey3", "testValue3");

var k = _OrderedDictionary.Keys.GetEnumerator();
var v = _OrderedDictionary.Values.GetEnumerator();

while (k.MoveNext() && v.MoveNext()) {
    var key = k.Current; var value = v.Current;
}

항목은 추가 된 순서대로 반환됩니다.


5

연관 배열 (일명 해시 테이블)은 순서가 지정되어 있지 않으므로 요소를 상상할 수있는 방식으로 정렬 할 수 있습니다.

그러나 배열 키 (키만)를 가져 와서 알파벳순으로 (정렬 기능을 통해) 정렬 한 다음 작업 할 수 있습니다.

언어를 모르기 때문에 C # 샘플을 드릴 수는 없지만이 정도면 충분합니다.

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