2012-11-02 16 views
5

Sto cercando di accelerare un pezzo di codice che unisce due SortedLists.C# Unisci due liste ordinate (Unione?)

C# 4.0 generico 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); 
} 

Sto pensando che un sindacato al posto del ciclo foreach sarebbe più veloce, ma non so come implementare un sindacato su un SortedList. Se qualcuno potesse aiutarmi, lo apprezzerei.

Inoltre, se c'è un modo migliore per farlo nel complesso, sono aperto a suggerimenti.

+1

Solo un'idea, ma secondo [questa risposta] (http://stackoverflow.com/a/1754080/551322), potrebbe essere d'aiuto se si ordina la raccolta di input. – nrodic

+0

Grazie, i dati in ingresso provengono da elenchi ordinati in modo da renderli preordinati - osservando ciò nonostante potrei voler passare a SortedDictionary. –

+0

Perché stai cercando di velocizzare questo codice? Funziona male? – Enigmativity

risposta

2

L'unico modo in cui posso pensare di unire due istanze SortedList consiste nell'unirle, quindi convertirle in una ricerca, quindi prendere il primo elemento della collezione di ricerca per creare un dizionario.

Avrei bisogno di creare un dizionario perché lo SortedList supporta solo gli add-on uno-uno. Quindi l'unica altra opzione sarebbe quella di iniettare un dizionario nel costruttore SortedList.

Bottom line: Penso che il tuo codice attuale sia abbastanza decente così com'è. LINQ può aiutare a ridurre il codice a circa 2 righe (o una se sei masochista).

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

Grazie - risponde alle mie domande sui sindacati - tuttavia non rende il mio codice più veloce (probabilmente a causa della necessità di riconvertirlo in una SortedList), quindi non lo userò. Grazie ancora! –

+0

Sì, lo pensavo anche io. Il problema è che "SortedList.Union' non sembra rispettare" IEqualityComparer ".In tal caso, ** potrebbe ** essere leggermente più performante, poiché la conversione alla ricerca influirebbe sulla successiva conversione al dizionario. Inoltre, fa schifo che 'SortedList' non supporti in modo innato l'aggiunta di un intervallo di' KeyValuePairs' piuttosto che uno solo alla volta. – code4life

+0

Sì, questo in realtà fa molto più loop rispetto al codice originale, perché è ciò che fa linq in background. – theMayer

1

SortedSet ha un metodo UnionWith che fa ciò che si sta chiedendo. Ho creato la mia implementazione di SortedSet e funziona molto rapidamente.

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

Nevermind, ho riletto la tua domanda e si utilizza l'implementazione delle liste; tuttavia, se riesci a trovare un modo per creare un EqualityComparer invece di utilizzare una chiave specifica, potrebbe essere possibile adattare un SortedSet al tuo scopo.

+0

Grazie, ma SortedSet e SortedList non sono la stessa cosa. È la chiave/valore che mi sta rovinando e SortedSet non ha una chiave. - Inoltre spero di ottenere una sorta di esempio su come implementarlo. Posso fare ricerche per conto mio. –

+0

Anzi, le mie scuse. Tuttavia, guardando il tuo codice di esempio, stai cercando di eliminare i duplicati? – theMayer

+0

Nessuna chiave duplicata - Non credo che una SortedList possa avere comunque chiavi duplicate. I valori duplicati vanno bene. –