2012-11-02 6 views
5

Ich möchte ein Stück Code beschleunigen, das zwei SortedLists miteinander verbindet.C# Merge Two SortedLists (Union?)

C# 4.0 generic SortedList: http://msdn.microsoft.com/en-us/library/ms132319(v=vs.100).aspx

public Trait getTrait(decimal thisValue) 
{  
    if (ParentStructure != null && ParentStructure.RankedTraits.Count > 0) 
    { 
     SortedList<decimal, Trait> tempTraits = this.RankedTraits; 

     // Improve here (union?) 
     foreach (KeyValuePair<decimal, Trait> kvp in (ParentStructure.RankedTraits)) 
     { 
      if (!tempTraits.ContainsKey(kvp.Key)) 
      { 
       tempTraits.Add(kvp.Key, kvp.Value); 
      } 
     } 
     return _getTrait(tempTraits, thisValue); 
     } 
    } 
    return _getTrait(_rankTraits, thisValue); 
} 

Ich denke, dass eine Vereinigung statt die foreach Schleife schneller sein würde, aber ich weiß nicht, wie eine Gewerkschaft auf einem SortedList zu implementieren. Wenn mir jemand dabei helfen könnte, würde ich es begrüßen.

Auch, wenn es eine bessere Möglichkeit gibt, dies insgesamt zu tun, bin ich offen für Vorschläge.

+1

Nur eine Idee, aber nach [diese Antwort] (http://StackOverflow.com/a/1754080/551322), könnte es hilfreich sein, wenn Sie Input-Sammlung sortieren. – nrodic

+0

Danke, die Daten, die eingegeben werden, kommen aus sortierten Listen, so dass sie es vorsortiert machen sollten - mit Blick darauf, obwohl ich vielleicht zu einem SortedDictionary wechseln möchte. –

+0

Warum möchten Sie diesen Code beschleunigen? Funktioniert es schlecht? – Enigmativity

Antwort

2

Die einzige Möglichkeit, zwei Instanzen von SortedList zusammenzuführen, besteht darin, sie zu vereinigen, dann in ein Lookup zu konvertieren und dann das erste Element der Lookup-Sammlung zu einem Wörterbuch zu machen.

Ich müsste ein Wörterbuch machen, weil die SortedList nur eins-nach-eins unterstützt. Also wäre die einzige andere Option, ein Wörterbuch in den SortedList Konstruktor einzufügen.

Fazit: Ich denke, dass Ihr aktueller Code ziemlich anständig ist, wie es ist. LINQ kann dazu beitragen, den Code auf 2 Zeilen zu reduzieren (oder einen, wenn Sie ein Masochist sind).

SortedList<decimal, Traits> listA = new SortedList<decimal, Traits>(); 
SortedList<decimal, Traits> listB = new SortedList<decimal, Traits>(); 

listA.Add(1m, new Traits { FieldName = "One" }); 
listA.Add(2m, new Traits { FieldName = "Two" }); 
listA.Add(3m, new Traits { FieldName = "Three" }); 

listB.Add(1m, new Traits { FieldName = "One" }); 
listB.Add(4m, new Traits { FieldName = "Four" }); 
listB.Add(5m, new Traits { FieldName = "Five" }); 

var listUnion = listA.Union(listB).ToLookup(k => k.Key, v => v.Value) 
        .ToDictionary(k => k.Key, v => v.First()); 
var listMerged = new SortedList<decimal, Traits>(listUnion); 
+0

Danke - das beantwortet meine Fragen zu Gewerkschaften - aber es macht meinen Code nicht schneller (wahrscheinlich, weil ich ihn wieder in eine SortedList konvertieren muss), also werde ich ihn nicht benutzen. Danke noch einmal! –

+0

Ja, ich dachte das auch. Das Problem ist, dass die 'SortedList.Union' den IEqualityComparer nicht zu respektieren scheint.Wenn dies der Fall wäre, ** könnte es ** ein bisschen leistungsfähiger sein, weil die Umwandlung in die Suche die spätere Konvertierung in das Wörterbuch beeinflussen würde. Es ist auch irgendwie scheiße, dass 'SortedList' nicht von Haus aus das Hinzufügen einer Reihe von' KeyValuePairs' unterstützt und nicht nur einzeln. – code4life

+0

Ja, das macht tatsächlich viel mehr Looping als der ursprüngliche Code, denn das macht Linq im Hintergrund. – theMayer

1

SortedSet hat eine UnionWith-Methode, die das tut, was Sie fragen. Ich habe meine eigene Implementierung von SortedSet erstellt und es funktioniert sehr schnell.

http://msdn.microsoft.com/en-us/library/dd411939.aspx

Nevermind, ich wieder lesen Ihre Frage und Sie werden mit der Liste Umsetzung; Wenn Sie jedoch einen Weg finden, einen EqualityComparer zu erstellen, anstatt einen bestimmten Schlüssel zu verwenden, könnte es möglich sein, SortedSet an Ihren Zweck anzupassen.

+0

Danke, aber SortedSet & SortedList sind nicht dasselbe. Es ist der Schlüssel/Wert, der mich verpfuscht und SortedSet hat keinen Schlüssel. - Ich hoffe auch, ein Beispiel dafür zu bekommen, wie es umgesetzt werden kann. Ich kann selbst suchen. –

+0

In der Tat, meine Entschuldigung. Wenn Sie sich jedoch Ihren Beispielcode anschauen, versuchen Sie Dubletten zu eliminieren? – theMayer

+0

Keine doppelten Schlüssel - Ich glaube nicht, dass eine SortedList trotzdem doppelte Schlüssel haben kann. Doppelte Werte sind in Ordnung. –