Συχνά πρέπει να ταξινομήσω ένα λεξικό, που αποτελείται από κλειδιά & τιμές, ανά τιμή. Για παράδειγμα, έχω έναν κατακερματισμό λέξεων και αντίστοιχων συχνοτήτων, που θέλω να ταξινομήσω με βάση τη συχνότητα.
Υπάρχει μια SortedList
η οποία είναι καλή για μια μόνο τιμή (ας πούμε συχνότητα), που θέλω να την αντιστοιχίσω πίσω στη λέξη.
Το SortedDictionary διατάσσει με βάση το κλειδί, όχι με βάση την τιμή. Κάποιοι καταφεύγουν σε μια προσαρμοσμένη κλάση, αλλά υπάρχει κάποιος πιο καθαρός τρόπος;
Χρήση:
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));
Κοιτάζοντας τριγύρω και χρησιμοποιώντας κάποια χαρακτηριστικά της C# 3.0 μπορούμε να το κάνουμε αυτό:
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{
// do something with item.Key and item.Value
}
Αυτός είναι ο πιο καθαρός τρόπος που έχω δει και είναι παρόμοιος με τον τρόπο χειρισμού των hashes στη Ruby.
Σε υψηλό επίπεδο, δεν έχετε άλλη επιλογή από το να περπατήσετε σε ολόκληρο το λεξικό και να εξετάσετε κάθε τιμή.
Ίσως αυτό βοηθήσει: http://bytes.com/forum/thread563638.html Αντιγραφή/επικόλληση από τον John Timney:
Dictionary<string, string> s = new Dictionary<string, string>(),
s.Add("1", "ένα στοιχείο"),
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),
}
);