Gambas-it

Gambas3 => Programmazione => Topic aperto da: Sebastiano - 26 Febbraio 2018, 20:39:11

Titolo: Ordinare vettori separati
Inserito da: Sebastiano - 26 Febbraio 2018, 20:39:11
ciao a tutti,
premetto che sono nuovo del mondo gambas e avrei un piccolo problema:
ho 2 array ( array A che contiene i nomi e array B che contiene i punteggi), devo ordinare gli array in base al punteggio (i migliori 10) in modo da ottenere la classifica aggiornata quando aggiorno i punteggi. Come posso mettere in ordine un array in funzione dell'altro?
Mi spiego meglio, se ordino l'array con i punteggi (quindi dal punteggio più alto a quello più basso) come posso fare ad ottenere lo stesso ordine nel secondo array? e quindi al punteggio più alto il nome effettivo.....grazie
Avevo pensato di inserire i dati in un database e poi ordinarli, ma volevo sapere se c'e' una soluzione veloce usando le funzioni e gli array....grazie
e scusatemi in anticipo per la domanda da principiante
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 26 Febbraio 2018, 20:48:59

L'importante è considerare il "collegamento" necessario di ogni punteggio al rispettivo nome.
In fondo, la corrispondenza fra i due gruppi di dati è un elemento noto.

.......
Titolo: Re:aiutatemi, grazie
Inserito da: Sebastiano - 26 Febbraio 2018, 22:02:17
scusami ma non ho capito la risposta......sicuramente ho formulato male la domanda.

ho gli elementi dell'array A (Marco, Giorgio,Luca,Davide) e gli elementi dell'array B(15,32,18,50)
ora se io ordino in modo decrescente i valori dell'array B mi deve ordinare anche gli elementi dell'array A.......quindi
array B (50, 32,18,15 ) l'array A diventa (Davide, Giorgio,Luca,Marco)......
Grazie ancora di tutto........ :)
Titolo: Re:aiutatemi, grazie
Inserito da: Gianluigi - 26 Febbraio 2018, 22:19:14
Leggo solo ora il tuo quesito, intanto ti do il mio benvenuto  :ciao:
Non ho ben capito il perché i due array siano separati, perché non ne fai uno unico?
Potresti spiegarti meglio?

 :ciao:

P.S. Per cortesia puoi dare alla discussione un oggetto che descriva il problema? Altrimenti le future ricerche saranno più complicate.
Titolo: Re:aiutatemi, grazie
Inserito da: Top Fuel - 26 Febbraio 2018, 23:31:26
Basterebbe fare una miniclasse con 2 proprietà: Nome come stringa e Punteggio come intero.
Ti crei un array di quella classe, così i nomi sono già accoppiati con il relativo punteggio e poi ordini l'array in base ai punteggi.
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 27 Febbraio 2018, 00:36:54
ho gli elementi dell'array A (Marco, Giorgio,Luca,Davide) e gli elementi dell'array B(15,32,18,50)
ora se io ordino in modo decrescente i valori dell'array B mi deve ordinare anche gli elementi dell'array A.......quindi
array B (50, 32,18,15 ) l'array A diventa (Davide, Giorgio,Luca,Marco)......

Ora è più chiaro.
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 27 Febbraio 2018, 01:46:23
Basterebbe fare una miniclasse con 2 proprietà: Nome come stringa e Punteggio come intero.
Ti crei un array di quella classe, così i nomi sono già accoppiati con il relativo punteggio e poi ordini l'array in base ai punteggi.
Top Fuel ha centrato il nocciolo della questione, proponendoti la creazione di una specifica Classe priva di propri Eventi.
...e va benissimo.
In vero Gambas possiede già una risorsa che è paragonabile esattamentre ad una "Classe senza Eventi": la Struttura (http://www.gambas-it.org/wiki/index.php?title=Strutture:_dichiarazione_ed_uso).

Come Top Fuel aggiunge, è necessario creare una variabile vettoriale di quella Struttura, al fine di contenere le varie singole variabili di quel medesimo tipo di Struttura.

Propongo questo esempio, nel quale l'ordine dei nomi sarà adattato secondo l'ordine dei punteggi:
Codice: [Seleziona]
Public Struct RISULTATI
  nome As String
  punt As Byte
End Struct


Public Sub Main()
 
  Dim ri As RISULTATI
  Dim rrii As New RISULTATI[]
  Dim nuova As New RISULTATI[4]
  Dim nomi As String[]
  Dim punteggi, bb As Byte[]
  Dim b, c As Byte
   
' Imposta i valori iniziali per entrambi gli array:'
   nomi = ["Marco", "Giorgio", "Luca", "Davide"]
   punteggi = [15, 32, 18, 50]
   For b = 0 To nomi.Max
     ri = New RISULTATI
     ri.nome = nomi[b]
     ri.punt = punteggi[b]
     rrii.Push(ri)
   Next
   
   With bb = New Byte[]
' Passa il valore del membro oggetto dell'ordinamento ad un vettore di tipo omogeneo:
     For b = 0 To rrii.Max
       bb.Push(rrii[b].punt)
     Next 
' Effettua l'ordinamento (in questo caso di tipo "discendente"):
     bb.Sort(gb.Descent)
   End With
   
' Genera un nuovo vettore di tipo della Struttura "RISULTATI" contenente nei propri elementi le variabili del tipo Struttura "RISULTATI" "ordinati" in base al membro ".punt":'
   For b = 0 To bb.Max
     For c = 0 To rrii.Max
       If bb[b] = rrii[c].punt Then
         With nuova[b] = New RISULTATI
           .nome = rrii[c].nome
           .punt = rrii[c].punt
         End With
       Endif
     Next
   Next
   
' Verifica finale:'
   For b = 0 To nuova.Max
     Print nuova[b].punt, nuova[b].nome
   Next

End

......in buona sostanza abbiamo ordinato più variabili del tipo di una specifica Struttura in base ad un loro membro comune....

scusatemi in anticipo per la domanda da principiante
...e dunque questione certamente non da principiante.
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 27 Febbraio 2018, 02:21:05
...ma più elegantemente possiamo eliminare la complicazione dell'array di Strutture, prevedendo gli array nei membri della Struttura:   (https://www.tomshw.it/forum/s9/smilies/sisi.gif)

Codice: [Seleziona]
Public Struct RISULTATI
  nome[4] As String
  punt[4] As Byte
End Struct


Public Sub Main()

  Dim ri, nuova As New RISULTATI
  Dim nomi As String[]
  Dim punteggi, bb As Byte[]
  Dim b, c As Byte
   
   nomi = ["Marco", "Giorgio", "Luca", "Davide"]
   punteggi = [15, 32, 18, 50]
   For b = 0 To nomi.Max
     ri.nome[b] = nomi[b]
     ri.punt[b] = punteggi[b]
   Next

   With bb = New Byte[]
     For b = 0 To ri.nome.Max
       .Push(ri.punt[b])
     Next
     .Sort(gb.Descent)
   End With

   For b = 0 To bb.Max
     For c = 0 To bb.Max
       If bb[b] = ri.punt[c] Then
         With nuova
           .nome[b] = ri.nome[c]
           .punt[b] = ri.punt[c]
         End With
       Endif
     Next
   Next
     
   For b = 0 To nuova.nome.Max
     Print nuova.punt[b], nuova.nome[b]
   Next

End
Titolo: Re:aiutatemi, grazie
Inserito da: Gianluigi - 27 Febbraio 2018, 10:03:25
In attesa del cambio oggetto... io intendevo suggerire una cosa più semplice, del tipo:
Codice: [Seleziona]
Public Sub Main()

  Dim hPerNumero As String[] = ["50|Marco", "32|Giorgio", "15|Luca", "18|Davide"]
  Dim s As String
  Dim ss As String[]
 
  hPerNumero.Sort(gb.Descent)
 
  For Each s In hPerNumero
    s = Replace(s, "|", "    ")
    Print s
  Next
  Print String(19, "-")
  Print "|"; "NOME"; Space(7); "|"; "PUNTI"; "|"
  Print String(19, "-")
  For Each s In hPerNumero
    ss = Split(s, "|")
    Print "|"; ss[1]; Space(11 - Len(ss[1])); "|"; ss[0]; Space(5 - Len(ss[0])); "|"
    Print String(19, "-")
  Next

End

Ho postato (http://www.gambas-it.org/smf/index.php?topic=6163.msg43339#new) in area Progetti degli utenti un piccolo esempio  :ciao:
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 27 Febbraio 2018, 10:40:52
io intendevo suggerire una cosa
Una soluzione simile l'ho adottata (https://media.giphy.com/media/VB3FTofMhUdIk/giphy.gif) nel mio Sequencer Midi (http://www.gambas-it.org/smf/index.php?topic=5818) per unificare più variabili vettoriali
Titolo: Re:aiutatemi, grazie
Inserito da: Sebastiano - 27 Febbraio 2018, 23:23:51
Vi ringrazio per le risposte che mi avete dato......
se ho altri problemi saprò a chi rivolgermi...... :ciao:
Titolo: Re:aiutatemi, grazie
Inserito da: vuott - 27 Febbraio 2018, 23:29:11
se ho altri problemi saprò a chi rivolgermi......

...basterà semplicemente, come hai fatto in questa tua discussione, porre la domanda al forum: ci saranno sempre suoi membri ponti ad aiutarti.   :coder:



Colgo l'occasione per rinnovare la lista attuale dei collegamenti utili all'apprendimento del linguaggio Gambas:

Sito ufficiale di Gambas:
 - http://gambas.sourceforge.net/en/main.html

Wiki ufficiale di Gambas:
 - https://gambaswiki.org/wiki?l=it

Mailing List ufficiale di Gambas:
 - https://lists.gambas-basic.org/pipermail/user/

Forum, Wiki ed altri siti esistenti su Gambas:
 - https://gambas-es.org/
 - https://foro.gambas-es.org/forum.php
 - http://www.gambas-club.de/index.php
 - https://forum.gambas.one/
 - https://gambaslinux.fr/v2/
 - http://89.234.156.109/
 - http://www.gambas-it.org/wiki/index.php?title=Pagina_principale
 - https://gambas-buch.de/dwen/doku.php
 - https://de.wikibooks.org/wiki/Gambas
 - http://sologambas.blogspot.com/p/indice.html
 - https://jsbsan.blogspot.com/
 - http://captainbodgit.blogspot.com/search/label/Gambas
 - https://pigalore.miraheze.org/wiki/Main_Page
 - http://icculus.org/piga/
 - http://novatocodegambas.blogspot.com/

Testi, manuali e corsi esistenti:
 - https://cursogambas.blogspot.com/p/indice.html
 - https://github.com/jsbsan/Ejemplos-del-Curso-De-Gambas3
 - http://gambaswiki.org/wiki/doc/book?nh&l=en
 - https://en.wikibooks.org/wiki/Programming_Gambas_from_Zip
 - https://wordpress.gambas.one/a-book-by-gerry-buzolic/
 - https://wordpress.gambas.one/2020/04/10/the-gap-bg-project/


Ad ogni modo, suggerisco - come approccio teorico di studio a Gambas - quest'ordine di argomenti basilari, generali e preliminari per una comprensione migliore ed adeguata del linguaggio:
Titolo: Re:Ordinare vettori separati
Inserito da: Top Fuel - 28 Febbraio 2018, 21:49:15
Ma volendo, per l'ordinamento si può usare anche un algoritmo come il caro vecchio Bubblesort, per es. :
Codice: [Seleziona]
' Gambas class file

Public Struct RISULTATI
  nome As String
  punti As Byte
End Struct
Public rrii As New RISULTATI[]

Public Sub Form_Open()
Dim i As Byte
Dim ri As RISULTATI
Dim nomi As String[]
Dim punteggi As Byte[]
nomi = ["Marco", "Giorgio", "Luca", "Davide"]
punteggi = [15, 32, 18, 50]
For i = 0 To nomi.Max
     ri = New RISULTATI
     ri.nome = nomi[i]
     ri.punti = punteggi[i]
     rrii.Push(ri)
Next
Bubblesort
For i = 0 To 3
   Print rrii[i].nome
   Print rrii[i].punti
Next
End

Public Sub Bubblesort()
Dim i As Byte
Dim scambio As Boolean = True
While scambio = True
   scambio = False
   For i = 0 To rrii.Count - 2
      If rrii[i].punti < rrii[i + 1].punti Then
         Swap rrii[i], rrii[i + 1]
         scambio = True
      Endif
   Next
Wend
End
Titolo: Re:Ordinare vettori separati
Inserito da: vuott - 01 Marzo 2018, 00:15:15
    per l'ordinamento si può usare anche un algoritmo come il caro vecchio Bubblesort
Molto interessante.

Mi permetto solo di apportare una nota per perfezionare il tuo codice: poiché la variabile di tipo array è in sostanza un Puntatore all'Oggetto del tipo array, puoi eliminare la variabile Globale "rrii", riducendola a variabile automatica "locale" e passandola così "per Indirizzo" alla sotto-procedura "Bubblesort( )".
la variabile che funge da Puntatore a un Oggetto sovente è definita " Handle " (maniglia), che significa "una variabile associata a un oggetto complesso, che lo identifica". La maniglia è la protuberanza con la quale interagisci con l'Oggetto. In gambas, qualsiasi Oggetto (form, o altro) è in sostanza un " Handle ".

Tale sotto-procedura - che così diventa una vera e propria "Funzione" (poiché ritorna "per Indirizzo" un valore alla procedura chiamante) - assumerà, dunque, il seguente suo prototipo:
Codice: [Seleziona]
Public Function Bubblesort(risul As RISULTATI[ ])
La funzione chiamante ovviamente passerà, come suo unico parametro attuale, la variabile vettoriale di tipo della Struttura, come segue:
Codice: [Seleziona]
Bubblesort(rrii)
....e in modo egualmente evidente riceverà "per Indirizzo" una Struttura (la medesima che è stata passata, ma ora con i valori modificati dei suoi membri).

E' appena il caso di ricordare che il passaggio di valori "per Indirizzo" a una sotto-procedura/funzione, non crea una copia dell'Oggetto, o comunque del tipo, passato, come avviene invece nel passaggio "per Valore", ove si va ad occupare un'altra area di memoria (per generare la copia) di dimensioni pari a quella occupata dall'Oggetto (o dal tipo di valore) passato.
Va da sé che con il passaggio "per Valore", avendo due copie uguali, avremo due indirizzi di memoria che si riferiscono ovviamente a due aree di memoria riservate automaticamente di uguale dimensione, ...e quindi un consumo doppio delle risorse (ossia della memoria necessaria per il passaggio dei dati).
Il passaggio "per Indirizzo" fa in modo che la modifica avvenga direttamente ...all'indirizzo di memoria dell'Oggetto (o del tipo di valore) passato. Quindi non si crea una copia e non si deve così occupare altra memoria per il medesimo dato da passare.
Titolo: Re:Ordinare vettori separati
Inserito da: Top Fuel - 01 Marzo 2018, 21:37:26
Se non vado errante per passare un parametro come indirizzo e non per valore c'è l'istruzione ByRef. O serve solo per le Sub?
Titolo: Re:Ordinare vettori separati
Inserito da: vuott - 02 Marzo 2018, 02:12:57
Se non vado errante per passare un parametro come indirizzo e non per valore c'è l'istruzione ByRef.
Sì, Gambas fornisce, come risorsa dedicata in modo specifico per passare un valore "per Riferimento" (che è come dire "per Indirizzo"), la parola-chiave " ByRef ":
Codice: [Seleziona]
Public Sub Main()

  Dim vl As Integer
 
   vl = 10

   Funzione(ByRef vl)
 
   Print vl

End


Private Function Funzione(ByRef i As Integer)
 
  i *= 1000
 
End
Evidentemente la parola-chiave " ByRef " provvederà a passare alla Funzione chiamata l'indirizzo di memoria della variabile da passare come parametro attuale.

Come però sappiamo, noi possiamo utilizzare anche un Puntatore, o più precisamente "l'indirizzo di memoria della variabile" (di un tipo numerico o anche di tipo String), per effettuare un passaggio a una sotto-procedura (più segnatamente una Funzione).
Per avere l'indirizzo di memoria della variabile, da passare, dovremo utilizzare la funzione " VarPtr( ) ".
Questa modalità comporta, però, un lavoro più complesso all'interno della Funzione chiamata, in particolare se il valore passato attraverso il Puntatore deve essere manipolato, poiché - come sappiamo - per incidere sui dati presenti nell'area di memoria puntata da un Puntatore è assolutamente necessario l'uso delle risorse dei " Memory Stream ".

Esempio:
Codice: [Seleziona]
Public Sub Main()

  Dim vl As Integer
 
   vl = 10

   Funzione(VarPtr(vl))
 
   Print vl

End


Private Function Funzione(p As Pointer)
 
  Dim st As Stream

' 1) Dereferenziamo il Puntatore ricevuto;
' 2) Manipoliamo il suo valore originario contenuto nella variabile "i";
' 3) Scriviamo il nuovo valore nell'area di memoria puntata dal Puntatore "p";
   st = Memory p For Write
   Write #st, Int@(p) * 1000 As Integer
   st.Close
 
End
Titolo: Re:Ordinare vettori separati
Inserito da: vuott - 02 Marzo 2018, 15:22:39
Il passaggio "per Indirizzo" fa in modo che la modifica avvenga direttamente ...all'indirizzo di memoria dell'Oggetto (o del tipo di valore) passato. Quindi non si crea una copia e non si deve così occupare altra memoria per il medesimo dato da passare.
Ogni "Oggetto" di Gambas è innanzitutto costituito da più porzioni di memoria, organizzate secondo le specifiche Strutture previste dai sorgenti di Gambas per ciascun Oggetto, dedicate a immagazzinare i dati che caratterizzeranno gli Oggetti medesimi.

Da ciò deriva che, se un Oggetto è generato via codice, è possibile in talune circostanze (ove non siano richiesti gli Eventi disponibili dell'Oggetto in questione) evitare l'uso delle variabili Globali, per rappresentare l'Oggetto medesimo, e usare invece una variabile locale da passare " per Indirizzo " a una Funzione.

Mostriamo un breve codice con mero fine esemplificativo:
Codice: [Seleziona]
Public Sub Button1_Click()

  Dim vb As ValueBox
 
   With vb = New ValueBox(Me)
     .X = 100
     .Y = 100
     .W = 50
     .H = 30
     .Alignment = Align.Right
     .Value = 10
     
   End With
   
   Wait 2

   Funzione(vb)
 
   Wait 2
 
   vb.Value *= 4

End


Private Function Funzione(vlb As ValueBox)
 
  vlb.Value *= 1000
 
End