Newsgroup: it.comp.lang.visual-basic
Titolo: Collection: ricavare il Key dato l'Index

Creo una collection.
Ci collego n oggetti, ad esempio (usando delle stringhe per fare prima):
Collezione.Add "Pippo1", "Chiave01"
Collezione.Add "Pippo2", "Chiave02"
Collezione.Add "Pippo3", "Chiave03"
Collezione.Add "Pippo4", "Chiave04"
Se voglio ottenere un qualunque elemento, posso fare
Debug.Print Collezione.Item(1)
oppure, indifferentemente
Debug.Print Collezione.Item("Chiave01")
Per una serie di motivi, mi farebbe molto comodo ricavare la stringa Key
sapendo l'index, ossia, ricavare che all'elemento 1 corrisponde la key
"Chiave01", al 2 la "Chiave02", ecc...
Infatti, aggiungendo e rimuovendo elementi, la numerazione di Index varia,
mentre la Key resta legata all'elemento della collection, quindi non posso
basarmi su cose del tipo "La chiave è uguale a "Chiave" & Format(n,"00")".
Potrei risolvere tutto con una classe o un tipo utente, ma prima volevo
sapere se qualcuno ha un metodo più elegante...
Ciao e grazie
Alberto

 sapendo l'index
adXCollct.zip su sito comune.
Non ha un Key(Item) poichè il legame tramite ashing è unidirezionale, però
puoi sapere la chiave dato l'indice dell'elemento (Key(Index)), quindi
basterebbe un loop su questo fino a trovare l'elemento interessato.
Ciao
--
' // Initialize the expression evaluator
Engines.Evaluator = CreateObject("
http://www.neodatatype.net
")
' // you can find resources for and from the NG here!
Me.SitoComune = "
http://www.it-lang-vb.net
"

 basterebbe un loop su questo fino a trovare l'elemento interessato.
Beh, diciamo che a me serve proprio Key(Index), quindi ci dovremmo essere.
Lunedì lo provo.
Grazie
Alberto

Altra domanda interessante.
Se voglio sapere se è presente un elemento in una collection con una
determinata key come posso fare?

 determinata key come posso fare?
Sempre adXCollct.zip su sito comune.
Metodo KeyExists()


 determinata key come posso fare?
Brutalmente:
Function ItemInCollection(Coll As Object, Key As Variant) As Boolean
   On Error Resume Next
   Dim Obj As Object
   Set Obj = Coll.Item(Key)
   ItemInCollection = Err = 0
   Set Obj = Nothing
End Function
Per quanto riguarda il problema di ottenere la chiave di un elemento della
collection, non esistendo un metodo ti conviene senz'altro implementarti una
tua classe (è una cosa molto semplice e sicuramente ci saranno esempi in
giro) che abbia un metodo "Key" che ti ritorna, dato l'indice, la chiave da
una collection delle chiavi. In pratica, MyCollection sarà una classe che
conserva i dati in una Collection privata e le chiavi in un'altra
Collection. Ad ogni Add e Remove dovrai quindi lavorare su entrambe le
collection per mantenerle allineate. Questa tecnica ti eviterà di eseguire
loop poderosi (con tanto di strcomp) sulla collection per trovare un
elemento.
--
rumplestiltskin

 elemento.
Beh, in realtà questa è la soluzione più classica.
Altra soluzione, che adotto molto spesso, è quella di inserire nella
collection le istanze di una mia classe, che offra come proprietà 1) la
variabile originale che volevo mettere in collection e 2) una stringa che mi
indica la key.
In questo modo, posso usare la sintassi Collection.Item(index).Key, ma devo
creare una classe per ogni tipo di cosa che voglia inserire in collection.
Domani lavorerò sul codice di Zanna.
Come prima cosa dovrò togliere quell'API che ho visto dichiarata in alto, e
vedere quali metodi o proprietà risentiranno della mancanza. Se si tratta di
metodi che non mi servono, o che posso implementare senza Api, mi sembra una
ottima soluzione, perchè consente di sfruttare la stessa classe di
collection per qualunque 'roba' ci si debba inserire.
Ciao
Alberto

 creare una classe per ogni tipo di cosa che voglia inserire in collection.
Forse mi hai frainteso. Non ti suggerivo di creare una coppia di collection
per ogni collection, ma di implementare una nuova classe collection che
faccia il lavoro in maniera trasparente. In questo modo non devi fare
neppure la fatica di usare una tua classe con un puntatore all'oggetto. Il
tuo codice infatti sarebbe:
Dim cls as MyPointer
Dim coll as new Collection
set cls.Pointer = Obj
cls.Key = "PIPPO"
coll.Add cls,cls.Key
-> coll(x).Key ritorna la chiave (fra l'altro è late bound)
Io dico invece di fare così:
Dim coll as new MyCollection
coll.Add obj,"PIPPO"
-> coll.Key(x) ritorna la chiave (fra l'altro è early bound)
--
rumplestiltskin

 Forse mi hai frainteso.
Non mi sembra di aver frainteso.
Tu mi hai suggerito esattamente quanto già postato da Zanna (una classe
simile a Collection, ma che offra metodi e proprietà estese, fra cui la
possibilità di leggere il Key dato l'Index).
Io, ma solo per pura accademia, ho postato come ho fatto finora.
Ciao
Alberto

 possibilità di leggere il Key dato l'Index).
Non ho visto la classe di Zanna (solo che era nel sito comune, mi pare di
ricordare) ma l'idea è quella. Mi pareva che tu avessi capito diversamente,
scusa.
--
rumplestiltskin