Πώς μπορείτε να ταξινομήσετε ένα λεξικό με βάση την τιμή;

Συχνά πρέπει να ταξινομήσω ένα λεξικό, που αποτελείται από κλειδιά & τιμές, ανά τιμή. Για παράδειγμα, έχω έναν κατακερματισμό λέξεων και αντίστοιχων συχνοτήτων, που θέλω να ταξινομήσω με βάση τη συχνότητα.

Υπάρχει μια SortedList η οποία είναι καλή για μια μόνο τιμή (ας πούμε συχνότητα), που θέλω να την αντιστοιχίσω πίσω στη λέξη.

Το SortedDictionary διατάσσει με βάση το κλειδί, όχι με βάση την τιμή. Κάποιοι καταφεύγουν σε μια προσαρμοσμένη κλάση, αλλά υπάρχει κάποιος πιο καθαρός τρόπος;

Λύση

Χρήση:

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

myList.Sort(
    delegate(KeyValuePair pair1,
    KeyValuePair 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));
Σχόλια (11)

Κοιτάζοντας τριγύρω και χρησιμοποιώντας κάποια χαρακτηριστικά της C# 3.0 μπορούμε να το κάνουμε αυτό:

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

Αυτός είναι ο πιο καθαρός τρόπος που έχω δει και είναι παρόμοιος με τον τρόπο χειρισμού των hashes στη Ruby.

Σχόλια (5)

Σε υψηλό επίπεδο, δεν έχετε άλλη επιλογή από το να περπατήσετε σε ολόκληρο το λεξικό και να εξετάσετε κάθε τιμή.

Ίσως αυτό βοηθήσει: http://bytes.com/forum/thread563638.html Αντιγραφή/επικόλληση από τον John Timney:

Dictionary s = new Dictionary(),
s.Add("1", "ένα στοιχείο"),
s.Add("2", "c Item"),
s.Add("3", "b Item"),

List myList = new List(s),
myList.Sort(
    delegate(KeyValuePair firstPair,
    KeyValuePair nextPair)
    {
        return firstPair.Value.CompareTo(nextPair.Value),
    }
);
Σχόλια (2)