Cum a face tu a sorta un dicționar de valoare?

De multe ori am la fel un dicționar, alcătuit de chei & valori, de valoare. De exemplu, am un hash de cuvinte și respectiv frecvențe, că vreau să comand de frecvență.

Există o Motorola care este bun pentru o singură valoare (sa zicem frecvență), pe care vreau să-l înapoi la harta cuvântul.

SortedDictionary ordinele de cheie, nu valoarea. Unii recurg la o clasa personalizat, dar nu există un mod mai curat?

Comentarii la întrebare (1)
Soluția

Utilizare:

using System.Linq.Enumerable;
...
List myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair pair1,
    KeyValuePair pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

De când te - 're de direcționare .NET 2.0 sau mai sus, puteți simplifica acest lucru în lambda sintaxă-l's echivalente, dar mai scurte. Daca're de direcționare .NET 2.0 puteți folosi doar această sintaxă daca're folosind compilatorul de la Visual Studio 2008 (sau mai sus).

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Comentarii (11)

Folosi LINQ:

Dictionary myDict = new Dictionary();
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;

Acest lucru ar permite, de asemenea, o mare flexibilitate în care puteți selecta top 10, 20 10%, etc. Sau dacă utilizați cuvântul tău indicele de frecvență pentru type-ahead, ai putea, de asemenea, includStartsWith` clauza fel de bine.

Comentarii (12)
var ordered = dict.OrderBy(x => x.Value);
Comentarii (9)

Căutarea în jurul valorii de, și folosind unele C# 3.0 caracteristici putem face acest lucru:

foreach (KeyValuePair item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

Acest lucru este cel mai curat mod de am'am văzut și este similar cu Ruby mod de manipulare hash-uri.

Comentarii (5)

Puteți sorta un Dicționar de valoare și salvați-l înapoi la sine (astfel încât, atunci când foreach peste valorile ieși în ordine):

dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);

Sigur, aceasta nu poate fi corect, dar funcționează.

Comentarii (8)

La un nivel înalt, nu aveți altă alegere decât să se plimbe prin întregul Dicționar și de a uita-te la fiecare valoare.

Poate asta te ajuta: http://bytes.com/forum/thread563638.html Copiere/Lipire de John Timney:

`` c# Dicționar<string, string> s = noul Dicționar<string, string>(); s.Adauga("1", "punct"); s.Adauga("2", "c Articol"); s.Adauga("3", "b Articol");

Listă<KeyValuePair<string, string>> myList = new Lista<KeyValuePair<string, string>>(s); myList.Sort( delegat(KeyValuePair<string, string> firstPair, KeyValuePair<string, string> nextPair) { reveni firstPair.Valoare.CompareTo(nextPair.Valoare); } ); ``

Comentarii (2)

Te'd nu fi capabil de a sorta un dicționar oricum. Ele nu sunt de fapt ordonat. Garanțiile pentru un dicționar care sunt cheia și valoarea colecțiilor sunt iterable, iar valorile pot fi recuperate prin index sau cheie, dar nu există nici o garanție de nici o ordine anume. Prin urmare, ai nevoie pentru a obține perechea valoare de nume într-o listă.

Comentarii (7)

Nu sorta intrările în Dicționar. Dicționar clasa în .NET este implementat ca un hashtable - această structură de date nu este sortable prin definiție.

Dacă aveți nevoie pentru a fi capabil de a itera peste colecția dvs. (de cheie) - aveți nevoie pentru a utiliza SortedDictionary, care este implementat ca un Arbore Binar de Căutare.

În cazul tău, cu toate acestea sursa structură este lipsită de relevanță, deoarece este clasificate în funcție de un domeniu diferit. Încă mai trebuie să le sorteze în funcție de frecvență și se pune într-o nouă colecție clasificate în funcție de domeniul relevant (de frecvență). Deci în această colecție frecvențele sunt cheile și cuvintele sunt valorile. De multe cuvinte pot avea aceeași frecvență (și ai de gând să-l folosească ca o cheie) nu puteți folosi nici Dicționarul nici SortedDictionary (au nevoie de chei unice). Acest lucru te lasă cu un Motorola.

Eu nu't înțeleg de ce insistă să mențină un link la original, produs in principal/primul dicționar.

Dacă obiectele din colecție au o structură mai complexă (mai multe câmpuri) și ai nevoie pentru a fi capabil de a accesa în mod eficient/le sorta folosind diferite câmpuri drept chei - probabil Ai nevoie de un custom structură de date care va fi format de stocare principal care suportă O(1) inserare și de ștergere (LinkedList) și mai multe indexare structuri - Dicționare/SortedDictionaries/SortedLists. Aceste indicii ar folosi unul din domeniile din clasa complex ca o cheie și un indicator/referință la LinkedListNode în LinkedList ca o valoare.

Tu ar trebui să coordoneze și inserții de mutări pentru a menține indicii dvs. în sincronizare cu principalele colectie (LinkedList) și absorbțiile ar fi destul de scump am'd cred. Acest lucru este similar cu modul în care baza de date a indicilor de lucru - acestea sunt fantastic pentru căutări, dar au devenit o povară atunci când aveți nevoie pentru a efectua mai multe insetions și eliminări.

Toate cele de mai sus este justificată numai dacă aveți de gând să faci unele look-up grele de prelucrare. Dacă aveți nevoie doar să le transmită odată sortate în funcție de frecvență, apoi ai putea să producă o listă de (anonim) tupluri:

var dict = new SortedDictionary();
// 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);
}
Comentarii (0)
Dictionary dic= new Dictionary();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Comentarii (1)

Un fel de valori

Acest lucru arată cum pentru a sorta valorile într-un Dicționar. Vom vedea un program de consolă puteți compila în Visual Studio și a alerga. Se adaugă cheile de la un Dicționar și apoi le sortează valorile lor. Amintiți-vă că Dicționarul de cazuri nu sunt inițial sortate în orice mod. Vom folosi LINQ orderby de cuvinte cheie într-o declarație interogare.

Clauză OrderBy Program care sortează Dicționar [C#]

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary(5);
        dictionary.Add("cat", 1);
        dictionary.Add("dog", 0);
        dictionary.Add("mouse", 5);
        dictionary.Add("eel", 3);
        dictionary.Add("programmer", 2);

        // Order by values.
        // ... Use LINQ to specify sorting by value.
        var items = from pair in dictionary
                orderby pair.Value ascending
                select pair;

        // Display results.
        foreach (KeyValuePair pair in items)
        {
            Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
        }

        // Reverse sort.
        // ... Can be looped over in the same way as above.
        items = from pair in dictionary
        orderby pair.Value descending
        select pair;
    }
}

Ieșire

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
Comentarii (0)

Sau pentru a te distra, ai putea folosi LINQ extensia bunătate:

var dictionary = new Dictionary { { "c", 3 }, { "a", 1 }, { "b", 2 } };
dictionary.OrderBy(x => x.Value)
  .ForEach(x => Console.WriteLine("{0}={1}", x.Key,x.Value));
Comentarii (0)

Sortarea o `SortedDictionary lista pentru a lega într-un ListView control folosind VB.NET:

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:








Comentarii (0)

Cel mai simplu mod de a obține un sortate Dicționar este de a folosi construit în SortedDictionary clasa:

//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary sortedSections = null;
if (sections != null)
{
    sortedSections = new SortedDictionary(sections);
}

sortedSections va conține sortate versiune de "secții"

Comentarii (3)

Celelalte răspunsuri sunt bune, dacă tot ce vrei este de a avea un "temporar" listă clasificate în funcție de Valoare. Cu toate acestea, dacă doriți să aveți un dicționar clasificate în funcție de "Cheie" care automatically synchronizes cu un alt dicționar, care este clasificate în funcție de "Valoare", ai putea folosi `Bijection<K1, K2> clasa.

Bijection<K1, K2> vă permite pentru a inițializa de colectare cu două dicționare existente, deci, dacă doriți unul dintre ei să fie sortate, și vrei ca celălalt să fie sortate, ai putea crea bijection cu cod ca

var dict = new Bijection(new Dictionary(), 
                               new SortedDictionary());

Puteți utiliza dict ca orice dicționar mod normal (se implementeaza IDictionary<K, V>), și apoi apel dict.Invers pentru a obține "invers" de dicționar, care este clasificate în funcție de "Valoare".

Bijection<K1, K2> este parte a Loyc.Collections.dll, dar daca vrei, ai putea pur și simplu copiați codul sursă în propriul proiect.

Notă: în cazul În care există mai multe chei cu aceeași valoare, puteți't folosi Bijection, dar ai putea sincroniza manual între un obișnuitîn Dicționarul<Cheie,Valoare> și BMultiMap<Value,Key>.

Comentarii (1)

Să presupunem că avem un dicționar ca

   Dictionary dict = new Dictionary();
   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. puteți să utilizați temporar dicționar pentru a stoca valori ca :
        Dictionary dctTemp = new Dictionary();

        foreach (KeyValuePair pair in dict.OrderBy(key => key.Value))
        {
            dctTemp .Add(pair.Key, pair.Value);
        }
Comentarii (0)

De fapt, în C#, Dicționare dint au sort() metode, ca sunt mai interesați într-un fel de valori, tu cant a lua valori de până la tine să le ofere cheie, pe scurt, ai nevoie pentru a itera prin ele, folosind LINQ's Pentru De,

var items = new Dictionary();
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
}

puteți face un truc,

var sortedDictByOrder = items.OrderBy(v => v.Value);

sau

var sortedKeys = from pair in dictName
            orderby pair.Value ascending
            select pair;

sale, de asemenea, depinde de ce fel de valori sunt stocate, este singur (cum ar fi string, int) sau mai multe (cum ar fi Lista, Matrice, definite de utilizator clasa), dacă un singur puteți face lista de apoi aplica un fel. dacă definite de utilizator clasa, atunci acea clasă trebuie să pună în aplicare icomparable, ClassName: în aplicare icomparable<Nume> și suprascrie compareTo(ClassName c) deoarece acestea sunt mult mai rapide decât LINQ, și mai mult orientate obiect.

Comentarii (0)

Având aveți un dicționar aveți posibilitatea să sortați-le direct pe valorile de mai jos, folosind o singură linie:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Comentarii (1)

Puteți sorta Dicționar de valoare și pentru a obține rezultatul în dicționar folosind codul de mai jos:

Dictionary  ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Comentarii (2)