답변:
사용하다:
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
트릭을 수행하는 트릭을 만들 수도 있습니다 (사실 키를 허용하지만 키를 사용하면 값을 얻을 수 있음). ;-)