2010-09-30 10 views
8

Al momento sto utilizzando una classe personalizzata derivata da HashSet. C'è un punto del codice quando seleziono articoli sotto certe condizioni:Selezionare un elemento per indice da un HashSet .NET

var c = clusters.Where(x => x.Label != null && x.Label.Equals(someLabel));

Funziona bene e ottengo questi elementi. Ma c'è un modo per ricevere un indice di quell'elemento all'interno della collezione da usare con il metodo ElementAt, invece di interi oggetti?

Sembrerebbe più o meno così:

var c = select element index in collection under certain condition; 
int index = c.ElementAt(0); //get first index 
clusters.ElementAt(index).RunObjectMthod();

Is iterare manualmente su tutta la collezione un modo migliore? Devo aggiungere che è in un ciclo più grande, quindi questa clausola Where viene eseguita più volte per diverse stringhe someLabel.

Modifica

Che cosa ho bisogno per questo? clusters è un insieme di cluster di alcuni documenti raccolti. I documenti sono raggruppati in cluster per argomenti di similarità. Quindi uno degli ultimi passaggi dell'algoritmo è scoprire l'etichetta per ciascun cluster. Ma l'algoritmo non è perfetto e talvolta crea due o più cluster con la stessa etichetta. Quello che voglio fare è semplicemente unire questi cluster in uno grande.

risposta

14

Gli indirizzi generalmente non hanno indici. Se la posizione è importante per te, dovresti usare un List<T> invece di (o forse anche un) set.

Ora SortedSet<T> in .NET 4 è leggermente diverso, in quanto mantiene un ordine di valori ordinati. Tuttavia, non implementa ancora IList<T>, quindi l'accesso per indice con ElementAt sarà lento.

Se si potesse fornire maggiori dettagli sul motivo per cui si desidera questa funzionalità, sarebbe utile. Il tuo caso d'uso non è molto chiaro al momento.

+0

Ho aggiunto una descrizione più dettagliata di un problema come richiesto :) – Ventus

+0

@Ventus: Ciò non spiega in realtà perché è necessario l'indice. Se vuoi solo eseguire un metodo per ogni elemento corrispondente, un semplice ciclo foreach è sicuramente la strada da seguire ... hai una ragione particolare per desiderare un indice? –

+0

Ovviamente le mie abilità linguistiche (intendo inglese) non sono perfette, anche se volevo modificare contemporaneamente 2 elementi nella collezione. Tuttavia, il tuo suggerimento di usare 'List' invece di set era una buona idea, quindi il problema è risolto e la tua risposta è accettata. – Ventus

3

Non esiste un indice con un set di hash. Uno dei modi in cui l'hash set guadagna efficacia in alcuni casi è il non doverli mantenere.

Anche io non vedo quale sia il vantaggio qui. Se si dovesse ottenere l'indice e quindi utilizzarlo, ciò sarebbe meno efficace del semplice ottenimento dell'elemento (ottenere l'indice sarebbe altrettanto efficiente, e quindi si avrà un'operazione supplementare).

Se si desidera eseguire diverse operazioni sullo stesso oggetto, tenere semplicemente l'oggetto.

Se si vuole fare qualcosa di parecchi oggetti, lo fanno sulla base di iterazione attraverso di loro (normale foreach o fare foreach sui risultati di un Where() etc.). Se vuoi fare qualcosa su diversi oggetti, e poi fare qualcos'altro su questi stessi oggetti, e devi farlo in tali batch, piuttosto che fare tutte le operazioni nello stesso foreach, quindi memorizzare i risultati dello Where() in un List<T>.

5

Nel caso in cui si conservino elementi in HashSet e talvolta è necessario ottenere elementi per indice, considerare l'utilizzo del metodo di estensione ToList() in tali situazioni. Quindi usi le funzionalità di HashSet e poi approfitti degli indici.

HashSet<T> hashset = new HashSet<T>(); 

//the special situation where we need index way of getting elements 
List<T> list = hashset.ToList(); 

//doing our special job, for example mapping the elements to EF entities collection (that was my case) 

//we can still operate on hashset for example when we still want to keep uniqueness through the elements 
+1

È sicuro? Penso che quando si aggiungono elementi a HashSet è possibile riordinare gli articoli e le successive chiamate a ToList() potrebbero non produrre sempre lo stesso ordine. Questo è solo un sospetto, non ho guardato il codice e MSDN non ha rivelato molto. – uriDium

+0

@uriDium Definire "sicuro". Il punto non era che le chiamate successive mantenessero lo stesso ordine, ma semplicemente per eseguire una funzione con alcuni oggetti. – Wolfzoon

Problemi correlati