JSON e LSL (2 di 4)

Dopo aver iniziato a trattare di JSON in LSL nella parte precedente in questo secondo articolo esamineremo alcune delle operazioni elementari che si possono eseguire con JSON e introdurremo anche il concetto di array multidimensionale che questo tipo di struttura ci consente di utilizzare.


LEGGERE un valore

La prima grossa differenza che incontriamo rispetto all’uso dei List è come possiamo recuperare i valori al loro interno. Nel caso di un’array JSON dovremo utilizzare la funzione llJsonGetValue (), la quale prevede come parametri il nome dell’array e l’indice del valore che vogliamo leggere incapsulato tra parentesi quadre, ovvero:

string mio_array_test_1 = "[ 123, <123.0, 58, 23>, 34 ]";
llJsonGetValue( "mio_array_test_1 ", [0]);

Il quale restituirà una stringa contente “123”, se vogliamo utilizzare questo valore come integer dovremo far precedere alla chiamata della funzione l’operatore di cast (integer).

mettendo a confronto JSON e List avremo cioè:

integer var_1 = (integer)llJsonGetValue( mio_array_test_1 , [0]);
integer var_2 = llLIst2Integer( mio_array_test_2, 0);

 


MODIFICARE un valore

Per modificare il valore di un elemento JSON, LSL ci mette a disposizione un’altra funzione, llJsonSetValue(), la quale prevede oltre al nome dell’array e alla posizione anche il valore da inserire:

mio_array_test1 = llJsonSetValue(mio_array_test_1, [0], (string)246);

in questo modo il valore dell’elemento alla posizione zero diventerà 246 sostituendosi al precedente valore che era 123. Da notare la presenza dell’operatore di cast (string) obbligatorio in quanto, come abbiamo detto l’intero array JSON di fatto non è altro che una stringa, per cui se vogliamo scrivere qualcosa dentro di essa dobbiamo assicurarci che venga inserito come se fosse una sequenza di caratteri, ovvero una stringa da inserire dentro.

Fare la stessa cosa con un List corrisponderebbe a:

mio_array_test_2 = llListReplaceList(mio_array_test_2 , [246], 0, 0);
//versione essenziale non ottimizzata

 


AGGIUNGERE un valore (in coda all’array)

Un’altra operazione basica per gli array consiste nell’aggiungere un nuovo valore in coda alla lista, la cosa può essere fatta ricorrendo sempre a llJsonSetValue(), ma utilizzando la costante JSON_APPEND al posto del valore dell’indice, ovvero:

mio_array_test1 = llJsonSetValue(mio_array_test_1, [JSON_APPEND], (string)555);

la stessa operazione con List corrisponderebbe a:

mio_array_test_2 += 555; 
//versione essenziale non ottimizzata

 


CANCELLARE un valore

Con un approccio simile a quanto visto per le aggiunte, è sufficiente utilizzare una costante specifica, in questo caso JSON_DELETE, per indicare che si vuole rimuovere un dato elemento dei un array, ecco un esempio:

//Prima: [13.444, "rosso", "magenta", 45] (4 elementi)
mio_array_test1 = llJsonSetValue(mio_array_test_1, [1], JSON_DELETE );
//Dopo: [13.444, "magenta", 45] (3 elementi)

la stessa operazione con List corrisponderebbe a:

//Prima: [13.444, "rosso", "magenta", 45]
mio_array_test2 = ListItemDelete(mio_array_test2, "rosso");
//Dopo: [13.444, "magenta", 45]

 


 CONFRONTARE due array tra loro

Dato che, come abbiamo detto, un elemento JSON in LSL di fatto non è altro che una stringa, di fatto per confrontare due elementi JSON non dobbiamo fare altro che verificare l’uguaglianza di due stringhe tra loro:

if ( mio_array_test_1 == mio_array_test_A ) { ... }
//dove mio_array_test_A è un altro array JSON

operazione cioè del tutto identica a quella che faremo se avessimo due liste da confrontare tra loro:

if ( mio_array_test_2 == mio_array_test_B ) { ... }
//dove mio_array_test_B è un'altra List

Ci sono molte altre operazioni basiche sugli array, ma per il momento ci fermiamo qui, in quanto per operazioni come il conteggio degli elementi di un array nel caso di JSON le cose si fanno più complesse ed è necessario prendere prima confidenza con le peculiarità non ancora esaminate di questo tipo di dato.

Array multidimensionali

La maggior parte dei linguaggi di programmazione prevede l’utilizzo di array a n dimensioni, array cioè in cui un valore non è identificato da un singolo indice numero, ma da una coppia di indici (array bidimensionali) o più (si parla in questi casi genericamente di array multidimensionali).

Un esempio di array bidimensionale potrebbe essere quello in cui vogliamo memorizzare l’altezza (in metri) l’età (in giorni) e la posizione di una serie di avatar.

Un’operazione del genere non è direttamente possibile con le List, in quanto esse sono strettamente monodimesionali. Nel caso delle liste infatti è necessario ricorrere alle cosiddette strided list, che però complicano non di poco la gestione globale dell’array stesso.

Nel caso di JSON le cose sono più semplici, infatti ogni array JSON oltre a poter contenere valori può contenere anche….altri array JSON al suo interno!

facciamo un primo esempio:

//definisco due array JSON (altezza, età, posizione)
string utenteA ="[ 1.80, 201, <145, 54, 23> ]";
string utenteB ="[ 2.65, 99, 12, <199, 85, 23> ]";

//definisco un terzo array JSON che contiene tutti e due i precedenti
string elenco_utenti = "[ utenteA, utenteB ]";

Per estrarre un dato valore ricorreremo sempre a llJsonGetValue, ma in questo caso dovremo porre attenzione all’indice che passiamo alla funzione, se ad esempio volessimo sapere i giorni dell’utente A dovremo scrivere le ‘coordinate’ del valore in questione ovvero:

... = (cast)llJsonGetValue( elenco_utenti, [0,1] );

che ci restituirà 201, mentre per leggere la posizione memorizzata dell’utenteB:

... = (cast)llJsonGetValue( elenco_utenti, [1,2] );

che ci restituirà <199, 85, 23>.

Starà a noi in qualità di scripter sapere come dover poi gestire il valore estratto (se vogliamo scriverlo lo estrarremo come stringa, se vogliamo fare dei conteggi lo estrarremo come intero e via dicendo.

Per sovrascrivere un valore utilizzeremo invece llJsonSetValue(), utilizzando la stessa logica:

elenco_utenti = llJsonSetValue( elenco_utenti, [0,1], (string)100 );
//cambia il valore dell'età memorizzato relativamente a quel dato utente

 


L’esempio precedente, ovvero quello relativo al conteggio dei giorni ci dà l’opportunità di mostrare alcuni usi di queste funzioni.
Invece che dover essere noi a dover inserire il numero di giorni potremo dire allo script di aggiornare tale valore ogni volta che trascorre un giorno (aumentandolo di 1), e questo è possibile fare attraverso l’uso combinato delle due funzioni llJsonGetValue() e llJsonSetValue()

Possiamo cioè pensare di fare una cosa di questo tipo:

1) ogni nuovo giorno lo script legge con llJsonGetValue() il valore dell’età dell’utente.
2) aumenta di una unità il il valore letto.
3) memorizza con llJsonSetValue il nuovo valore al posto del precedente.

Potremo scrivere cioè:

integer eta_utenteA = (integer)llJsonGetValue( elenco_utenti, [0,1] ); 
eta_utenteA++;
elenco_utenti = llJsonSetValue(elenco_utenti, [0,1]m (string)eta_utenteA]);

ma potremo anche ‘comprimere’ il tutto in:

elenco_utenti = llJsonSetValue(elenco_utenti, [0,1]m (string) ( (integer)llJsonGetValue( elenco_utenti, [0,1] )++ );

Forse non comprensibilissimo alla prima occhiata ma molto compatto e senza aver bisogno di ricorrere a variabili temporanee come eta_utenteA.

…e se conoscessimo a priori il numero di utenti nel nostro array (es. 10 utenti in totale) potremo aggiornarli tutti in un’unico ciclo del tipo:

integer numero_utenti_totali = 10;
integer cont;
for (cont= 0; cont < numero_utenti_totali; cont++){
  elenco_utenti = llJsonSetValue(elenco_utenti, [cont,1], (string)((integer)llJsonGetValue( elenco_utenti, [cont,1] )++ );
}

 


Non c’è limite al numero di elementi che possiamo mettere dentro un array, nè al numero di array che possiamo mettere dentro un’altro array (come nel caso di cui sopra), di fatto possiamo anche immaginare situazioni ibride, in cui un array contiene al suo interno sia array che valori, sta alla nostra abilità di scripter decidere come utilizzare al meglio questa versatilità.

string elenco_misto = "[ 150.3, utenteA, 9999, utenteB, 12, 3686.5 ]";

E per ora è tutto, nella prossima parte affronteremo i JSON Object, che rappresentano un modo  per gestire strutture dati complesse molto comodo e intuitivo, utile in parecchie occasioni.

Posted in LSL and tagged , , , , , , , .

Leave a Reply

Your email address will not be published.