2012-05-08 17 views
22

Attualmente ho la seguente sintassi (la lista è una lista che contiene oggetti con molte proprietà diverse (dove Title è uno di loro):Trova elemento in ObservableCollection senza utilizzare un ciclo

for (int i=0; i < list.Count; i++) 
{ 
    if(title == list[i].Title) 
    { 
    //do something 
    } 
} 

Come posso accedere al list[i].Title senza dover ricorrere a tutta la mia collezione? Dal momento che la mia lista tende a ingrandirsi, questo può influire sulle prestazioni del mio programma

Ho una sintassi molto simile sul mio programma (accesso alle proprietà pubbliche tramite un ciclo for e indice) Ma è certo che ci debba essere un modo migliore ed elegante per farlo?

Il metodo find sembra essere un'opzione poiché il mio elenco contiene oggetti.

+0

Cerca LINQ su oggetti. – Phil

+0

È possibile utilizzare linq, ad esempio [Trova] (http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx) oppure è possibile implementare il proprio dizionario con il supporto per [INotifyCollectionChanged] (http: // msdn .microsoft.com/it-it/library/system.collections.specialized.inotifycollectionchanged.aspx) – dowhilefor

+0

Un dizionario ha una ricerca molto veloce sulla chiave ma la chiave deve essere unica. Dal momento che il titolo non è unico, è necessario un ciclo. Ottimizza la classe per essere sicuro che il titolo ottenga; non è sciatto Se l'oggetto ha una chiave primaria interna, allora sostituisci GetHashCode con la chiave. – Paparazzi

risposta

36

Non so che cosa si intende esattamente , ma technially parlando, questo non è possibile senza un ciclo.

può essere che si intende utilizzare un LINQ, come ad esempio:

list.Where(x=>x.Title == title) 

Vale la pena ricordare che l'iterazione su non è saltato, ma semplicemente avvolto nella query LINQ.

Spero che questo aiuti.

EDIT

In altre parole, se si davvero preoccupato per le prestazioni, tenere codifica il modo in cui già facendo. Altrimenti scegli LINQ per sintassi più concisa e chiara.

+0

Quindi in pratica la mia sintassi va bene? Mi stavo solo chiedendo la performance, quindi la mia domanda. – PeterP

+0

Di solito è più veloce di LINQ, ma come puoi vedere, è molto più code line, LINQ è molto più consecutivo nella sua scrittura. – Tigran

+0

Ok, grazie, credo che rimarrò con le mie affermazioni perché le prestazioni sono davvero importanti nel mio programma. – PeterP

25

Qui viene Linq:

var listItem = list.Single(i => i.Title == title); 

viene generata un'eccezione se non c'è voce corrispondente al predicato. In alternativa, c'è SingleOrDefault.

Se si desidera una collezione di oggetti corrispondenti al titolo, c'è:

var listItems = list.Where(i => i.Title == title); 
+1

Questa è la risposta per chiunque cerchi di trovare un oggetto che soddisfi uno specifico criterio. – visc

1

Siete alla ricerca di una collezione basata hash (come un dizionario o hashset), che l'ObservableCollection non lo è. La soluzione migliore potrebbe essere derivare da una raccolta basata su hash e implementare INotifyCollectionChanged che ti darà lo stesso comportamento di ObservableCollection.

1

ObservableCollection è un elenco, quindi se non si conosce la posizione dell'elemento è necessario esaminare ciascun elemento fino a trovare quello previsto.

Possibile ottimizzazione Se i tuoi elementi sono ordinati usa una ricerca binaria per migliorare le prestazioni altrimenti usa un dizionario come indice.

3

Considera di creare un indice. Un dizionario può fare il trucco. Se hai bisogno della semantica della lista, sottoclasse e mantieni l'indice come membro privato ...

2

Suggerirei di archiviarli in un Hashtable. È quindi possibile accedere a un elemento nella raccolta utilizzando la chiave, è una ricerca molto più efficiente.

var myObjects = new Hashtable(); 
myObjects.Add(yourObject.Title, yourObject); 
... 
var myRetrievedObject = myObjects["TargetTitle"]; 
+0

Puoi anche considerare l'uso di un dizionario used2could

0

Bene, se si dispone di N oggetti ed è necessario ottenere il titolo di tutti loro è necessario utilizzare un ciclo. Se hai solo bisogno del titolo e vuoi davvero migliorare questo, forse puoi creare un array separato contenente solo il titolo, questo migliorerebbe le prestazioni. È necessario definire la quantità di memoria disponibile e la quantità di oggetti che è possibile gestire prima di dire ciò può danneggiare le prestazioni e in ogni caso la soluzione cambierebbe il progetto del programma e non l'algoritmo.

4

ho dovuto usarlo per aggiungere una condizione, se non è necessario l'indice

using System.Linq; 

uso

if(list.Any(x => x.Title == title){ 
// do something here 
} 

questo vi dirà se tutte le variabili soddisfa la vostra data condizione.

Problemi correlati