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

ψήφοι
671

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

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

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

Δημοσιεύθηκε 02/08/2008 στις 01:40
πηγή χρήστη
Σε άλλες γλώσσες...                            


17 απαντήσεις

ψήφοι
473

Χρησιμοποιήστε 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;

Αυτό θα επιτρέψει επίσης την μεγάλη ευελιξία σε ότι μπορείτε να επιλέξετε το top 10, 20 10%, κ.λπ. Ή εάν χρησιμοποιείτε δείκτη συχνότητας λέξη σας για type-ahead, θα μπορούσε επίσης να περιλαμβάνει StartsWithρήτρα, καθώς και.

Απαντήθηκε 04/08/2008 στις 16:22
πηγή χρήστη

ψήφοι
459

Χρήση:

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, μπορείτε να χρησιμοποιήσετε μόνο αυτή τη σύνταξη αν χρησιμοποιείτε τον compiler από το Visual Studio 2008 (ή παραπάνω).

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Απαντήθηκε 02/08/2008 στις 02:15
πηγή χρήστη

ψήφοι
179
var ordered = dict.OrderBy(x => x.Value);
Απαντήθηκε 11/11/2010 στις 18:16
πηγή χρήστη

ψήφοι
148

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

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

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

Απαντήθηκε 02/08/2008 στις 01:43
πηγή χρήστη

ψήφοι
140

Μπορείτε να ταξινομήσετε ένα λεξικό με βάση την αξία και να το αποθηκεύσετε πίσω στην ίδια (έτσι ώστε όταν foreach πάνω οι τιμές βγαίνουν σε σειρά):

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

Σίγουρα, μπορεί να μην είναι σωστή, αλλά λειτουργεί.

Απαντήθηκε 22/06/2011 στις 11:26
πηγή χρήστη

ψήφοι
56

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

Ίσως αυτό βοηθά: http://bytes.com/forum/thread563638.html Αντιγραφή / Επικόλληση από τον 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);
    }
);
Απαντήθηκε 02/08/2008 στις 01:47
πηγή χρήστη

ψήφοι
22

Ποτέ δεν ήθελα να είναι σε θέση να ταξινομήσετε ένα λεξικό ούτως ή άλλως. Δεν είναι στην πραγματικότητα διέταξε. Οι εγγυήσεις για ένα λεξικό είναι ότι τα βασικά και την αξία των συλλογών είναι iterable, και οι τιμές μπορούν να ανακτηθούν από το δείκτη ή το κλειδί, αλλά εδώ δεν αποτελεί εγγύηση για κάποια συγκεκριμένη σειρά. Ως εκ τούτου, θα πρέπει να πάρετε το ζεύγος αξία όνομα σε μια λίστα.

Απαντήθηκε 19/12/2008 στις 23:47
πηγή χρήστη

ψήφοι
16

Δεν ταξινομήσετε τις καταχωρήσεις στο λεξικό. Λεξικό τάξη στην ΝΕΤ υλοποιείται ως hashtable - η δομή των δεδομένων δεν είναι υπό διαλογή εξ ορισμού.

Εάν πρέπει να είναι σε θέση να επαναλάβει πάνω από τη συλλογή σας (με κλειδί) - θα πρέπει να χρησιμοποιήσετε SortedDictionary, το οποίο υλοποιείται ως δυαδική αναζήτηση δέντρο.

Στην περίπτωσή σας, ωστόσο η δομή πηγή έχει σημασία, επειδή είναι ταξινομημένο από διαφορετικό τομέα. Θα πρέπει ακόμα να ταξινομήσετε ανά συχνότητα και το βάζουμε σε μια νέα συλλογή κατατάσσονται σύμφωνα με το σχετικό πεδίο (συχνότητας). Έτσι, σε αυτή τη συλλογή οι συχνότητες είναι τα κλειδιά και τα λόγια είναι αξίες. Δεδομένου ότι πολλές λέξεις μπορεί να έχουν την ίδια συχνότητα (και θα έχετε την ευκαιρία να το χρησιμοποιήσει ως βασικό) δεν μπορείτε να χρησιμοποιήσετε ούτε λεξικό ούτε SortedDictionary (που απαιτούν ενιαία πλήκτρα). Αυτό σας αφήνει με ένα SortedList.

Δεν καταλαβαίνω γιατί επιμένουν στη διατήρηση μια σύνδεση με το αρχικό στοιχείο στην κύρια / πρώτη λεξικό σας.

Αν τα αντικείμενα της συλλογής σας είχε μια πιο σύνθετη δομή (περισσότερα πεδία) και θα έπρεπε να είναι σε θέση να αποτελεσματικά πρόσβασης / τα ταξινομήσετε χρησιμοποιώντας πολλά διαφορετικά πεδία, όπως τα πλήκτρα - Θα χρειαστεί κατά πάσα πιθανότητα μια δομή δεδομένων έθιμο που θα αποτελείται από το κύριο αποθήκευσης που υποστηρίζει O (1) εισαγωγή και την αφαίρεση (LinkedList) και διάφορες δομές ευρετηρίασης - Λεξικά / SortedDictionaries / SortedLists. Οι δείκτες αυτοί θα χρησιμοποιήσει ένα από τα πεδία από το συγκρότημα τάξη σας ως βασικό και ένα δείκτη / αναφορά στην LinkedListNode στο LinkedList ως αξία.

Θα πρέπει να συντονίσουν τις προσθήκες και αφαιρέσεις για να κρατήσει τους δείκτες σας σε συγχρονισμό με την κύρια συλλογή (LinkedList) και τις απορροφήσεις θα είναι αρκετά ακριβό είχα σκεφτεί. Αυτό είναι παρόμοιο με το πώς λειτουργούν οι δείκτες της βάσης δεδομένων - είναι φανταστικό για αναζητήσεις, αλλά να γίνει ένα βάρος που θα χρειαστεί να εκτελέσετε πολλές insetions και διαγραφές.

Όλα τα παραπάνω είναι δικαιολογημένη μόνο εάν πρόκειται να κάνετε κάποια look-up βαριά επεξεργασία. Αν το μόνο που χρειάζεται για την έξοδο τους μία φορά κατατάσσονται σύμφωνα με τη συχνότητα τότε θα μπορούσε να παράγει μόνο μια λίστα (ανώνυμο) πλειάδες:

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);
}
Απαντήθηκε 13/12/2012 στις 07:19
πηγή χρήστη

ψήφοι
12
Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Απαντήθηκε 20/07/2015 στις 11:01
πηγή χρήστη

ψήφοι
10

τιμές Ταξινόμηση

Αυτό δείξει πώς να ταξινομήσετε τις τιμές σε ένα λεξικό. Βλέπουμε ένα πρόγραμμα κονσόλας που μπορεί να συγκεντρώσει το Visual Studio και το τρέξιμο. Προσθέτει κλειδιά για ένα λεξικό και, στη συνέχεια, να τα ταξινομεί με τις τιμές τους. Να θυμάστε ότι λεξικό περιπτώσεις δεν είναι αρχικά ταξινομηθεί με οποιοδήποτε τρόπο. Χρησιμοποιούμε τη λέξη-κλειδί orderby LINQ σε δήλωσή του ερωτήματος.

OrderBy Πρόγραμμα ρήτρα που ταξινομεί λεξικό [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;
    }
}

Παραγωγή

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
Απαντήθηκε 20/07/2012 στις 10:49
πηγή χρήστη

ψήφοι
10

Ή για διασκέδαση, μπορείτε να χρησιμοποιήσετε κάποια 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));
Απαντήθηκε 30/06/2010 στις 12:12
πηγή χρήστη

ψήφοι
9

Ταξινόμηση μια SortedDictionaryλίστα για να συνδεθεί σε ένα ListViewέλεγχο χρησιμοποιώντας 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:

<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>
Απαντήθηκε 23/04/2010 στις 10:36
πηγή χρήστη

ψήφοι
5

Οι άλλες απαντήσεις είναι καλό, αν το μόνο που θέλετε είναι να έχουμε μια «προσωρινή» λίστα ταξινομημένο κατά τιμή. Ωστόσο, εάν θέλετε να έχετε ένα λεξικό κατατάσσονται σύμφωνα με Keyότι συγχρονίζεται αυτόματα με ένα άλλο λεξικό που κατατάσσονται σύμφωνα με Value, θα μπορούσατε να χρησιμοποιήσετε την Bijection<K1, K2>τάξη .

Bijection<K1, K2> σας δίνει τη δυνατότητα να προετοιμάσει την συλλογή με τα δύο υπάρχοντα λεξικά, οπότε αν θέλετε ένα από αυτά να είναι αδιαχώριστα, και θέλετε το άλλο να διευθετηθεί, θα μπορούσατε να δημιουργήσετε bijection σας με κωδικό όπως

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

Μπορείτε να χρησιμοποιήσετε dictόπως κάθε κανονικό λεξικό (εφαρμόζει IDictionary<>), και στη συνέχεια να καλέσετε dict.Inverseγια να πάρει το «αντίστροφο» λεξικό που ταξινομείται κατά Value.

Bijection<K1, K2>είναι μέρος της Loyc.Collections.dll , αλλά αν θέλετε, μπορείτε απλά να αντιγράψετε τον κώδικα στο δικό σας έργο.

Σημείωση : Σε περίπτωση που υπάρχουν πολλά κλειδιά με την ίδια τιμή, δεν μπορείτε να χρησιμοποιήσετε Bijection, αλλά θα μπορούσε να το χέρι συγχρονίσετε μεταξύ ενός συνηθισμένου Dictionary<Key,Value>και BMultiMap<Value,Key>.

Απαντήθηκε 26/02/2016 στις 07:15
πηγή χρήστη

ψήφοι
5

Ο ευκολότερος τρόπος για να πάρετε μια ταξινόμηση λεξικό είναι να χρησιμοποιήσετε την ενσωματωμένη στην 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

Απαντήθηκε 02/04/2010 στις 23:36
πηγή χρήστη

ψήφοι
4

Ας υποθέσουμε ότι έχουμε ένα λεξικό όπως

   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);
        }
Απαντήθηκε 02/02/2015 στις 10:46
πηγή χρήστη

ψήφοι
-2

Δεδομένου έχετε ένα λεξικό, μπορείτε να τα ταξινομήσετε άμεσα σε αξίες με τη χρήση κάτω από το ένα σκάφος της γραμμής:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Απαντήθηκε 31/05/2014 στις 23:30
πηγή χρήστη

ψήφοι
-2

Μπορείτε να ταξινομήσετε το Λεξικό με βάση την αξία και να πάρει το αποτέλεσμα στο λεξικό χρησιμοποιώντας τον παρακάτω κώδικα:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Απαντήθηκε 24/07/2012 στις 13:24
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more