c# initialize - Come si ordina un dizionario in base al valore?




dictionary fill (15)

Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);

Spesso devo ordinare un dizionario, composto da chiavi e valori, in base al valore. Ad esempio, ho un hash di parole e rispettive frequenze, che voglio ordinare per frequenza.

C'è una SortedList che va bene per un singolo valore (diciamo la frequenza), che voglio ricondurre alla parola.

SortedDictionary ordini per chiave, non valore. Alcuni ricorrono a una lezione personalizzata , ma c'è un modo più pulito?


O per divertimento potresti usare qualche bontà di estensione LINQ:

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

Ordina valori

Mostra come ordinare i valori in un dizionario. Vediamo un programma di console che puoi compilare in Visual Studio ed eseguire. Aggiunge le chiavi a un dizionario e poi le ordina in base ai loro valori. Ricorda che le istanze del dizionario non vengono inizialmente ordinate in alcun modo. Usiamo la parola chiave orderQ LINQ in una dichiarazione di query.

OrderBy Clause Program che ordina Dictionary [C #]

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

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary<string, int>(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<string, int> 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;
    }
}

Produzione

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5

Il modo più semplice per ottenere un dizionario ordinato è utilizzare la classe 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 contiene la versione ordinata delle sections


Uso:

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);
    }
);

Dal momento che hai scelto come target .NET 2.0 o versione successiva, puoi semplificare questo nella sintassi lambda: è equivalente, ma più breve. Se stai utilizzando .NET 2.0, puoi utilizzare questa sintassi solo se stai utilizzando il compilatore di Visual Studio 2008 (o successivo).

var myList = aDictionary.ToList();

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

Non saresti mai in grado di ordinare un dizionario comunque. Non sono effettivamente ordinati. Le garanzie per un dizionario sono che la chiave e le collezioni di valori sono iterabili, e i valori possono essere recuperati per indice o chiave, ma qui non c'è garanzia di alcun ordine particolare. Quindi è necessario ottenere la coppia valore nome in una lista.


È possibile ordinare il dizionario in base al valore e ottenere il risultato nel dizionario utilizzando il seguente codice:

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

Usa 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;

Ciò consentirebbe anche una grande flessibilità in quanto è possibile selezionare i primi 10, 20 10%, ecc. Oppure se si utilizza l'indice di frequenza delle parole per la type-ahead , è possibile includere anche la clausola StartsWith .


Ad un livello elevato, non hai altra scelta che percorrere l'intero dizionario e osservare ciascun valore.

Forse questo aiuta: http://bytes.com/forum/thread563638.html Copia / Incolla da John Timney:

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);
    }
);

Dato che hai un dizionario puoi ordinarli direttamente sui valori usando sotto una fodera:

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

Guardando intorno e usando alcune funzionalità del C # 3.0 possiamo fare questo:

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

Questo è il modo più pulito che ho visto ed è simile al modo in cui Ruby gestisce gli hash.


Supponiamo di avere un dizionario come

   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) puoi usare il 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);
        }

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

Le altre risposte sono buone, se tutto quello che vuoi è avere una lista "temporanea" ordinata per Valore. Tuttavia, se si desidera disporre di un dizionario ordinato per Key che si sincronizza automaticamente con un altro dizionario ordinato per Value , è possibile utilizzare la Bijection<K1, K2> .

Bijection<K1, K2> ti permette di inizializzare la raccolta con due dizionari esistenti, quindi se vuoi che uno di essi sia non ordinato, e vuoi che l'altro sia ordinato, puoi creare la tua bijection con un codice come

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

È possibile utilizzare dict come qualsiasi dizionario normale (implementa IDictionary<K, V> ), quindi chiamare dict.Inverse per ottenere il dizionario "inverso" ordinato per Value .

Bijection<K1, K2> è parte di Loyc.Collections.dll , ma se vuoi, puoi semplicemente copiare il codice sorgente nel tuo progetto.

Nota : nel caso in cui vi siano più chiavi con lo stesso valore, non è possibile utilizzare Bijection , ma è possibile sincronizzare manualmente tra un Dictionary<Key,Value> normale Dictionary<Key,Value> e un BMultiMap<Value,Key> .


function compare(propName) {
    return function(a,b) {
        if (a[propName] < b[propName])
            return -1;
        if (a[propName] > b[propName])
            return 1;
        return 0;
    };
}

objs.sort(compare("last_nom"));






c# .net sorting dictionary