2016-04-18 27 views
2

My Hash-Tabelle enthält (Schlüssel, Werte [])Wie kann ich sort (Custom Sort) Liste der Wörterbucheintrag von Wert

z:

myHashtable[keys, Values[]] 

myHashtable.Add[1, Value1]; 
myHashtable.Add[2, Value2]; 
myHashtable.Add[3, Value3]; 
myHashtable.Add[4, Value4]; 
myHashtable.Add[5, Value5]; 

Wo Value1; Wert2, Wert3, Wert4 und Wert5 lauten wie folgt.

Value1[name = "Smith"] 
Value1[Title= "Mr"] 
Value1[Salary = 1000] 
Value1[Identity = "S"] 

Value2[name = "Peter"] 
Value2[Title= "Mr"] 
Value2[Salary = 1000] 
Value2[Identity = "A"] 


Value3[name = "Tom"] 
Value3[Title= "Mr"] 
Value3[Salary = 1000] 
Value3[Identity = "C"] 


Value4[name = "Marry"] 
Value4[Title= "Ms"] 
Value4[Salary = 1000] 
Value4[Identity = ""] 

Value5[name = "Sam"] 
Value5[Title= "Mr"] 
Value5[Salary = 1000] 
Value5[Identity = "C"] 

Ich mag diese Dictionarylistenwerte bestellen, wo Identität mit „C“ Werten zuerst, dann „A“ dann „S“ und dann „“

Nach dem Ergebnis Sortier sein sollte wie folgt.

myHashtable.Add[3, Value3]; // Value3.Identity = "C" 
myHashtable.Add[5, Value5]; // Value5.Identity = "C" 
myHashtable.Add[2, Value2]; // Value2.Identity = "A" 
myHashtable.Add[1, Value1]; // Value1.Identity = "S" 
myHashtable.Add[4, Value4]; // Value4.Identity = "" 

Hier ist mein Versuch.

var result1 = new List<DictionaryEntry>(hashtable.Count); 
var result2 = new List<DictionaryEntry>(hashtable.Count); 
var result3 = new List<DictionaryEntry>(hashtable.Count);     
var result4 = new List<DictionaryEntry>(hashtable.Count); 


var result = new List<DictionaryEntry>(hashtable.Count); 

foreach (DictionaryEntry entry in hashtable) 
    { 
     result.Add(entry); 
    } 


       foreach (DictionaryEntry dictionaryEntry in result) 
       { 
        var t2 = dictionaryEntry.Value; 

        switch (t2.Identity) 
        { 
         case "C": 
          result1.Add(dictionaryEntry); 
          break; 
         case "A": 
          result2.Add(dictionaryEntry); 
          break; 
         case "S": 
          result3.Add(dictionaryEntry); 
          break; 
         case "": 
          result4.Add(dictionaryEntry); 
          break; 
         default: 
          break; 
        } 
       } 
       result1.ToList(); 
       result2.ToList(); 
       result3.ToList(); 


       var combinedResult = result1.Union(result2) 
        .Union(result3) 
        .Union(result4) 
        .ToDictionary(k => k.Key, v => v.Value).OrderByDescending(v => v.Value); 

Wie kann ich combinedResult sortieren, um mir die obige benutzerdefinierte sortierte Wörterbucheintragsliste zu geben?

Jede Hilfe wird sehr geschätzt. Danke

+0

Ihr 'Fall' macht (effektiv) nichts, denn nachdem es in ein Wörterbuch umgewandelt wurde, verschwindet die Reihenfolge. Ich würde wahrscheinlich eine Instanz von [SortedDictionary] (https://msdn.microsoft.com/en-us/library/f7fta44c (v = vs.110) .aspx) mit einem benutzerdefinierten Komparator liefern, wenn ich die Bestellung aufrechterhalten wollte. Wenn Sie nur die Ausgabe der aufgelisteten Enumeration wünschen, tun Sie das in der 'OrderByDescending'. –

Antwort

4

Wenn eine Dictionary-Datenstruktur mit einer Hashtabelle implementiert wird, werden die Daten unsortiert, um die amortisierten O (1) -Einfüge-/Lösch-/Aktualisierungsoperationen zu erreichen. Auf der anderen Seite, wenn das Dictionary mit einem ausgeglichenen Baum implementiert wird, sind die Operationen ein wenig langsamer O (logn), aber sie können in sortierter Weise (durch den Schlüssel) aufgelistet werden. Beispiel: Die C# -Wörterbuchimplementierung ist unsortiert, und eine C++ - Map wird sortiert (basierend auf einem rot-schwarzen Baum).
Angesichts der obigen Angaben (Sie können die Daten nicht so sortieren, wie Sie wollen im Wörterbuch). Was Sie tun können, ist speichern das Wörterbuch als Liste/Array und sortieren Sie dann nach dem von Ihnen gewünschten Komparator. Hier

ist ein Beispiel für ein Wörterbuch und einem benutzerdefinierten Vergleich, in dem Sie die Werte im Wörterbuch durch die Logik in der benutzerdefinierten Vergleich sortiert bekommen können:

public class Data 
{ 
    public string Name { get; set; } 
    public string Identity { get; set; } 
} 

public class CustomerComparer : IComparer<KeyValuePair<int, Data>> 
{ 
    private List<string> orderedLetters = new List<string>() { "C", "A", "S" }; 

    public int Compare(KeyValuePair<int, Data> str1, KeyValuePair<int, Data> str2) 
    { 
     return orderedLetters.IndexOf(str1.Value.Identity) - orderedLetters.IndexOf(str2.Value.Identity); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Data value1 = new Data { Name = "Name1", Identity = "S" }; 
     Data value2 = new Data { Name = "Name2", Identity = "A" }; 
     Data value3 = new Data { Name = "Name3", Identity = "C" }; 
     Data value4 = new Data { Name = "Name4", Identity = "C" }; 

     Dictionary<int, Data> unsortedDictionary = new Dictionary<int, Data>(); 
     unsortedDictionary.Add(1, value1); 
     unsortedDictionary.Add(2, value2); 
     unsortedDictionary.Add(3, value3); 
     unsortedDictionary.Add(4, value4); 

     var customSortedValues = unsortedDictionary.Values.OrderBy(item => item, new CustomerComparer()).ToArray(); 

     for (int i=0; i < customSortedValues.Length; i++) 
     { 
      var kvp = customSortedValues[i]; 
      Console.WriteLine("{0}: {1}=(Name={2}, Identity={3})", i, kvp.Key, kvp.Value.Name, kvp.Value.Identity); 
     } 
    } 
} 
//Output is: 
//0: Name3=C 
//1: Name4=C 
//2: Name2=A 
//3: Name1=S 

Sie können auch eine SortedDictionary verwenden (wie @ Clockwork-Muse schlägt vor) und übergibt einen ähnlichen CustomComparer wie im obigen Beispiel. Das hängt wirklich davon ab, was Ihre Anforderungen sind. Wenn Sie möchten, dass die Operationen schnell bleiben und nur die Werte sortiert werden müssen, zum Beispiel, Reporting, dann sortieren Sie einfach, wenn die Werte benötigt werden (wie in meinem Beispiel). Wenn Sie auf die sortierten Werte viel zugreifen, kann es sinnvoll sein, sie nur sortiert zu halten.

+0

Danke Itsik! Wie würden Sie die Eingabe in das Dictionary unsortedDictionary einfügen, wenn die Eingabe von einer Hashtable mit einem Schlüssel & Werten kommt? Wo Dictionary im obigen Beispiel? – MJA

+0

DictionaryEntry enthält ein 'Objekt' für Schlüssel und Wert, also können Sie sie einfach' dictionary.Add ((int) dictionaryEntry.Key, (Data) dictionaryEntry.Value) 'umsetzen. Gibt es einen bestimmten Grund, warum Sie eine Hashtable verwenden? Und nicht das generische Wörterbuch? – Itsik

+0

Nicht sicher, warum das Programm Hashtable noch verwendet. Aber hier versuche ich, die Eingabe (hashtable result) in unsortedDictionary einzufügen. Ich konnte jedoch den Schlüsselwortwert nicht in unsortedDictionary eingeben.'[Dictionary unsortedDictionary = neues Dictionary (); foreach (DictionaryEntry-Eintrag in HashtableResult) { unsortedDictionary.Add ((int) entry.Key, (Daten) entry.Value); } var customSortedValues ​​= unsortierteDictionary.Values.OrderBy (item => item, new CustomerComparer()). ToArray();] ' – MJA