답변:
사용하다:
using System.Linq.Enumerable;
...
List<KeyValuePair<string, string>> myList = aDictionary.ToList();
myList.Sort(
delegate(KeyValuePair<string, string> pair1,
KeyValuePair<string, string> pair2)
{
return pair1.Value.CompareTo(pair2.Value);
}
);
.NET 2.0 이상을 대상으로하기 때문에이를 람다 구문으로 단순화 할 수 있습니다. 이는 동등하지만 짧습니다. .NET 2.0을 대상으로하는 경우 Visual Studio 2008 이상의 컴파일러를 사용하는 경우에만이 구문을 사용할 수 있습니다.
var myList = aDictionary.ToList();
myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
myList.Sort((x,y)=>x.Value.CompareTo(y.Value));
IEnumerable되어 있으므로 다음과 같이 정렬 된 목록을 얻을 수 있습니다.var mySortedList = myDictionary.OrderBy(d => d.Value).ToList();
LINQ 사용 :
Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("one", 1);
myDict.Add("four", 4);
myDict.Add("two", 2);
myDict.Add("three", 3);
var sortedDict = from entry in myDict orderby entry.Value ascending select entry;
또한 상위 10, 20 10 % 등을 선택할 수 있다는 점에서 유연성이 뛰어납니다. 또는에 대한 단어 빈도 색인을 사용하는 경우 절도 type-ahead포함 할 수 있습니다 StartsWith.
IEnumerable<KeyValuePair<TKey, TValue>>또는 이어야합니다 OrderedDictionary<TKey, TValue>. 또는 SortedDictionary처음부터를 사용해야합니다 . 평원의 Dictionary경우 MSDN에는 "항목이 반환되는 순서는 정의되어 있지 않습니다"라고 명확하게 표시되어 있습니다. @ rythos42의 최신 편집은 비난하는 것 같습니다. :)
.ToDictionary- 표준 사전을 정렬 순서 보장하지 않습니다
var ordered = dict.OrderBy(x => x.Value);
둘러보고 C # 3.0 기능을 사용하면 다음과 같이 할 수 있습니다.
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{
// do something with item.Key and item.Value
}
이것은 내가 본 가장 깨끗한 방법이며 해시를 처리하는 루비 방법과 비슷합니다.
(for KeyValuePair<string, int> item in keywordCounts.OrderBy(key => key.Value) select item).ToDictionary(t => t.Key, t => t.Value)-당신의 대답에 작은 추가 :) 감사합니다, btw :)
값을 기준으로 사전을 정렬하고 다시 저장하면됩니다 (따라서 사전에 값이 순서대로 나옵니다).
dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
물론 정확하지는 않지만 작동합니다.
높은 수준에서 전체 사전을 살펴보고 각 값을 보는 것 외에 다른 선택은 없습니다.
아마도 이것이 도움이 될 것입니다 : http://bytes.com/forum/thread563638.html John Timney의 복사 / Pasting :
Dictionary<string, string> s = new Dictionary<string, string>();
s.Add("1", "a Item");
s.Add("2", "c Item");
s.Add("3", "b Item");
List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s);
myList.Sort(
delegate(KeyValuePair<string, string> firstPair,
KeyValuePair<string, string> nextPair)
{
return firstPair.Value.CompareTo(nextPair.Value);
}
);
어쨌든 사전을 정렬 할 수 없습니다. 그들은 실제로 주문되지 않았습니다. 사전에 대한 보장은 키 및 값 콜렉션이 반복 가능하며 인덱스 또는 키로 값을 검색 할 수 있지만 특정 순서를 보장하지는 않습니다. 따라서 이름 값 쌍을 목록으로 가져와야합니다.
사전에서 항목을 정렬하지 않습니다. .NET의 Dictionary 클래스는 해시 테이블로 구현됩니다.이 데이터 구조는 정의별로 정렬 할 수 없습니다.
컬렉션별로 키를 반복해야 할 경우-Binary Search Tree로 구현 된 SortedDictionary를 사용해야합니다.
그러나 소스 구조는 다른 필드로 정렬되기 때문에 소스 구조는 관련이 없습니다. 여전히 빈도별로 정렬하고 관련 필드 (빈도)별로 정렬 된 새 컬렉션에 배치해야합니다. 따라서이 모음에서 빈도는 키이고 단어는 값입니다. 많은 단어가 같은 빈도를 가질 수 있고 (키로 사용하려고 할 때) Dictionary 또는 SortedDictionary를 사용할 수 없습니다 (고유 키 필요). 그러면 SortedList가 남습니다.
주 / 처음 사전의 원래 항목에 대한 링크를 유지해야한다고 주장하는 이유를 이해하지 못합니다.
콜렉션의 오브젝트가 더 복잡한 구조 (더 많은 필드)를 가지고 있고 여러 다른 필드를 키로 사용하여 효율적으로 액세스 / 정렬 할 수 있어야하는 경우, 기본 스토리지로 구성된 사용자 정의 데이터 구조가 필요할 것입니다. O (1) 삽입 및 제거 (LinkedList) 및 여러 인덱싱 구조 (Dictionaries / SortedDictionaries / SortedLists)를 지원합니다. 이 인덱스는 복잡한 클래스의 필드 중 하나를 키로 사용하고 LinkedList의 LinkedListNode에 대한 포인터 / 참조를 값으로 사용합니다.
인덱스를 기본 컬렉션 (LinkedList)과 동기화하려면 삽입 및 제거를 조정해야하며 제거는 꽤 비쌀 것입니다. 이것은 데이터베이스 인덱스의 작동 방식과 유사합니다. 조회에는 환상적이지만 많은 삽입과 삭제를 수행해야 할 때 부담이됩니다.
위의 모든 사항은 조회 무거운 처리를 수행하려는 경우에만 정당화됩니다. 한 번만 주파수별로 정렬하여 출력 해야하는 경우 (익명) 튜플 목록을 생성 할 수 있습니다.
var dict = new SortedDictionary<string, int>();
// ToDo: populate dict
var output = dict.OrderBy(e => e.Value).Select(e => new {frequency = e.Value, word = e.Key}).ToList();
foreach (var entry in output)
{
Console.WriteLine("frequency:{0}, word: {1}",entry.frequency,entry.word);
}
VB.NET을 사용하여 컨트롤 SortedDictionary에 바인딩 할 목록 정렬 ListView:
Dim MyDictionary As SortedDictionary(Of String, MyDictionaryEntry)
MyDictionaryListView.ItemsSource = MyDictionary.Values.OrderByDescending(Function(entry) entry.MyValue)
Public Class MyDictionaryEntry ' Need Property for GridViewColumn DisplayMemberBinding
Public Property MyString As String
Public Property MyValue As Integer
End Class
XAML :
<ListView Name="MyDictionaryListView">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=MyString}" Header="MyStringColumnName"></GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=MyValue}" Header="MyValueColumnName"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
정렬 된 사전을 얻는 가장 쉬운 방법은 내장 SortedDictionary클래스 를 사용하는 것입니다 .
//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary<int, string> sortedSections = null;
if (sections != null)
{
sortedSections = new SortedDictionary<int, string>(sections);
}
sortedSections 정렬 버전이 포함됩니다 sections
SortedDictionary키별로 정렬합니다. OP는 값을 기준으로 정렬하려고합니다. SortedDictionary이 경우 도움이되지 않습니다.
sorteddictionary()적어도 1 마이크로 초 이상 승리했으며, 관리하기가 훨씬 쉽습니다 (사전과 0과 유사하게 쉽게 상호 작용하고 관리하는 것으로 다시 변환하는 오버 헤드가 이미 0 sorteddictionary임).
당신이 원하는 모든 것이 "일시적인"목록을 값으로 정렬하는 것이라면 다른 대답도 좋습니다. 당신으로 분류 사전 갖고 싶어하지만, Key그것을 자동으로 동기화 으로 분류되는 다른 사전으로 Value당신이 사용할 수있는, Bijection<K1, K2>클래스를 .
Bijection<K1, K2> 두 개의 기존 사전으로 컬렉션을 초기화 할 수 있으므로 그 중 하나를 정렬하지 않고 다른 하나를 정렬하려면 다음과 같은 코드로 궤적을 만들 수 있습니다
var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(),
new SortedDictionary<Value,Key>());
당신은 dict어떤 일반 사전처럼 (구현 IDictionary<K, V>) 사용할 수 있습니다 , 그리고 dict.Inverse정렬 된 "역"사전을 얻기 위해 호출 합니다 Value.
Bijection<K1, K2>Loyc.Collections.dll의 일부 이지만 원하는 경우 소스 코드 를 자신의 프로젝트에 간단히 복사 할 수 있습니다.
참고 : 값이 같은 여러 키가있는 경우, 당신은 사용할 수 없습니다 Bijection,하지만 당신은 수동으로 일반 사이에 동기화 할 수 Dictionary<Key,Value>와 BMultiMap<Value,Key>.
다음과 같이 사전이 있다고 가정하십시오.
Dictionary<int, int> dict = new Dictionary<int, int>();
dict.Add(21,1041);
dict.Add(213, 1021);
dict.Add(45, 1081);
dict.Add(54, 1091);
dict.Add(3425, 1061);
sict.Add(768, 1011);
1) 당신은 사용할 수 있습니다 temporary dictionary to store values as:
Dictionary<int, int> dctTemp = new Dictionary<int, int>();
foreach (KeyValuePair<int, int> pair in dict.OrderBy(key => key.Value))
{
dctTemp .Add(pair.Key, pair.Value);
}
실제로 C #에서 Dictionaries dint에는 sort () 메서드가 있습니다. 값별로 정렬하는 데 더 관심이 있기 때문에 키를 제공 할 때까지 값을 얻을 수 없습니다. 간단히 말해 LINQ의 Order By를 사용하여 값을 반복해야합니다.
var items = new Dictionary<string, int>();
items.Add("cat", 0);
items.Add("dog", 20);
items.Add("bear", 100);
items.Add("lion", 50);
// Call OrderBy method here on each item and provide them the ids.
foreach (var item in items.OrderBy(k => k.Key))
{
Console.WriteLine(item);// items are in sorted order
}
당신은 하나의 트릭을 할 수 있습니다
var sortedDictByOrder = items.OrderBy(v => v.Value);
또는
var sortedKeys = from pair in dictName
orderby pair.Value ascending
select pair;
또한 저장하는 값의 종류에 따라 달라집니다.
단일 (문자열, 정수) 또는 다중 (목록, 배열, 사용자 정의 클래스),
단일 값을 목록으로 만들 수 있으면 정렬을 적용하십시오.
사용자가 클래스를 정의한 경우 해당 클래스는 IComparable을 구현
ClassName: IComparable<ClassName>하고 compareTo(ClassName c)
LINQ보다 속도가 빠르고 객체 지향적이므로 재정의 해야합니다 .
필요한 네임 스페이스 : using System.Linq;
Dictionary<string, int> counts = new Dictionary<string, int>();
counts.Add("one", 1);
counts.Add("four", 4);
counts.Add("two", 2);
counts.Add("three", 3);
desc로 주문 :
foreach (KeyValuePair<string, int> kvp in counts.OrderByDescending(key => key.Value))
{
// some processing logic for each item if you want.
}
Asc로 주문 :
foreach (KeyValuePair<string, int> kvp in counts.OrderBy(key => key.Value))
{
// some processing logic for each item if you want.
}
아래 코드를 사용하여 사전을 값별로 정렬하고 결과를 사전으로 가져올 수 있습니다.
Dictionary <<string, string>> ShareUserNewCopy =
ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
pair => pair.Value);
사전이 있다고 가정하면 하나의 라이너를 사용하여 값을 직접 정렬 할 수 있습니다.
var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
IComparer트릭을 수행하는 트릭을 만들 수도 있습니다 (사실 키를 허용하지만 키를 사용하면 값을 얻을 수 있음). ;-)