Difference between revisions of "Category:LSL List/it"

From Second Life Wiki
Jump to navigation Jump to search
Line 134: Line 134:
<lsl>miaLista = [];</lsl>
<lsl>miaLista = [];</lsl>


====Passing a List Into a Function====
====Passare una lista in una funzione====


Passing a list into a function is little different than passing any other data type, however, there are some useful cases to be aware of:
Passare una lista in una funzione è un po' differente dal passare qualunque altro tipo di dato, comunque, ci sono alcuni casi utili di cui essere al corrente:


<lsl>myList = llListReplaceList(myList, ["myString"], 2, 2);</lsl>
<lsl>miaLista = llListReplaceList(miaLista, ["miaStringa"], 2, 2);</lsl>


In the above code, we call [[llListReplaceList]](), an innocent enough operation, however, due to the way passing of lists, and functions such as llListReplaceList(), [[llDeleteSubList]](), [[llList2List]]() and [[llListSortList()]] (and others), work, you can end up using two, three, or even four times the amount of memory required to store your list, just by calling that function! To avoid this problem, we can use a small piece of optimisation; if you know that the list you're passing into such a function will never be read again (for example if the result of the function will overwrite the list) then we can do this:
Nel codice qui sopra, chiamiamo [[llListReplaceList]](), un'operazione abbastanza innocente, comunque, a causa del modo in cui si passano le liste, e di come funzionano le funzioni come llListReplaceList(), [[llDeleteSubList]](), [[llList2List]]() e [[llListSortList()]] (e altre), potete finire con l'usare due, tre o persino quattro volte l'ammontare di memoria richiesto per immagazzinare la vostra lista, solo chiamando quella funzione! Per evitare questo problema, possiamo utilizzare un po' di ottimizzazione; se sapete che la lista che state passando in questa funzione non verrà mai più letta (ad esempio se il risultato della funzione sovrascriverà la lista) allora possiamo fare questo:


<lsl>myList = llListReplaceList((myList = []) + myList, ["myString"], 2, 2);</lsl>
<lsl>miaLista = llListReplaceList((miaLista = []) + miaLista, ["miaStringa"], 2, 2);</lsl>


The effect of this is to greatly reduce the memory usage, in both LSO-LSL and Mono VMs, and also reduce the fragmentation of memory. This can also work for other cases other than function-calls, for example when concatenating lists (above), you may find that this nearly eliminates any memory problem:
L'effetto di ciò è di ridurre enormemente l'utilizzo della memoria, in entrambe le VM LSO-LSL e Mono, e ridurrà anche la frammentazione della memoria. Questo funziona anche in altri casi che non siano chiamate a funzioni, per esempio quando si concatenano le liste (vedi sopra), potreste scoprire che questo sistema elimina quasi completamente qualsiasi problema di memoria:


<lsl>list list1 = ["a", "b", "c"];
<lsl>list lista1 = ["a", "b", "c"];
list2 = ["d", "e", "f"];
lista2 = ["d", "e", "f"];
list3 = (list1 = list2 = []) + list1 + list2;</lsl>
lista3 = (lista1 = lista2 = []) + lista1 + lista2;</lsl>


====Processing a List Into Another List====
====Processing a List Into Another List====

Revision as of 07:35, 31 December 2011

Una lista è un tipo speciale di dati che può contenere nessuno o più elementi.

Le liste vengono espresse tra parentesi quadre che ne racchiudono gli elementi; gli elementi al loro interno vengono separati da virgole.

Esempi: <lsl>[0,1,2,3,4]

["Sì","No","Magari"]</lsl>

(Nota: per essere chiari con coloro che hanno altri precedenti in programmazione, non esistono array nel LSL: solo liste.)


Tipi di dati differenti

Non tutti gli elementi in una lista devono essere lo stesso tipo di elemento. Nella stessa lista, potete immagazzinare stringhe, numeri interi, numeri frazionari, vettori, ecc. proprio fianco a fianco.

Esempio: <lsl>//una lista con un numero intero, un numero frazionario, una stringa e un vettore. [1,14.154,"Non è divertente?",<0,0,0>]</lsl>

Comunque, una lista non può contenere un'altra lista (es. non potete nidificarle).

<lsl>[1, "uno", 2, "due"] + [3, "tre"] restituisce [1, "uno", 2, "due", 3, "tre"]</lsl> non <lsl>[1, "uno", 2, "due", [3, "tre"]]</lsl>

Quando aggiungete un elemento a una lista, questa ricorda automaticamente che tipo di dato era quel valore.

Generalmente, poiché state aggiungendo qualcosa a una lista, sapete che tipo di dato sta in un determinato posto della lista, e lo estraete dalla lista con l'apposita funzione llList2<tipo> come ad esempio llList2String, llList2Vector, ecc. (più tardi ne diremo dell'altro).

Se per qualche motivo, però, dovete provare che tipo di dato sia un elemento in una lista, potete usare la funzione llGetListEntryType.

Suggerimento! Quando aggiungete un numero float (frazionario) a una lista, aggiungetelo sempre con un punto decimale (es. 1.0 invece di 1) per essere sicuri che sia conservato come frazionario.

Le liste possono essere tramutate direttamente in stringhe <lsl>default {

    touch_start(integer numero_totale)
   {   
       list a = ["abc",1,2,3.14,<0,0,0>];
       llOwnerSay((string)a); // risultato:  abc123.140000<0.000000, 0.000000, 0.000000>
   }

}</lsl>

oppure potete usare una condizione do while per pronunciare separatamente ciascun elemento della lista <lsl>default {

    touch_start(integer numero_totale)
   {   
       list a = ["abc","def","ghi","jkl","lmn","opq"];
       integer i;
       integer s = llGetListLength(a);
       do
       llOwnerSay(llList2String(a,i));
       while(s>++i);
   }

}</lsl>

Operazioni comuni con le liste

Contare la posizione in una lista Vs. lunghezza della lista

All'inizio è importante notare quanto segue (ciò potrebbe far inciampare persino le menti esperte quando sono stanche per la battaglia):

<lsl>["Sì","No","Magari"]</lsl>

La lunghezza di questa lista è 3, perché contiene 3 elementi. La lunghezza di una lista è restituita dalla funzione llGetListLength() :

<lsl>integer lunghezza = llGetListLength(miaLista);</lsl>

MA, il conteggio per determinare la posizione di un elemento nella sua lista (ovvero "indicizzazione") parte da 0 -- NON da 1.

La posizione di "Sì" nella lista precedente è 0, "No" è alla posizione 1, e "Magari" è alla posizione 2.

Conseguentemente, se avete 7 elementi in una lista, l'ultimo oggetto nella lista sarà alla posizione 6.

Perciò per ritrovare l'ultimo elemento in una lista, senza dover conoscere in anticipo in quale posizione sia, potete fare così:

<lsl>integer lunghezza = llGetListLength(miaLista); string oggetto = llList2String(miaLista,lunghezza - 1);</lsl>

Limiti delle liste

(Dal 20 febbraio 2011 questi limiti non sembrano essere in vigore sia per LSL che per Mono.)

Mentre uno script è in esecuzione, una lista può diventare crescere dinamicamente tanto larga quanto necessario, limitata solo dal quantitativo di memoria disponibile nello script.

Comunque, al momento di compilare (ovvero salvare), c'è un limite di 72 elementi per le liste predefinite incorporate nello script. Tali lunghe liste predefinite sono comuni, per esempio, quando qualcuno offre all'utente una pletora di colori tra cui scegliere.

Suggerimento! Se davvero vi servono 72 o più di queste scelte in una lista predefinita, create 2 (o più) liste che non turbano il compilatore, e unitele nello state_entry() o dovunque sia appropriato:

<lsl>listapiùgrande = listagrande01 + listagrande02;</lsl>

Aggiungere un elemento a una lista

Esistono svariati modi usati per aggiungere un elemento a una lista esistente tramite l'aggiunta all'inizio o alla fine:

  1. miaLista = [nuovo_oggetto] + miaLista; Metodo migliore per Mono-LSL
  2. miaLista = miaLista + [nuovo_oggetto];
  3. miaLista += [nuovo_oggetto];
  4. miaLista = (miaLista=[]) + miaLista + [nuovo_oggetto];
  5. miaLista = miaLista + miaLista;
  6. miaLista += nuovo_oggetto;
  7. miaLista = (miaLista=[]) + miaLista + nuovo_oggetto; Metodo migliore per LSO-LSL
Note
  • Dall'8 agosto 2009 il primo metodo permette risparmi significativi rispetto a qualunque altro metodo utilizzato in Mono-LSL.
    • Notate che aggiungere all'inizio il nuovo_oggetto senza parentesi nega qualsiasi risparmio di memoria in Mono-LSL.
    • Il primo metodo consumerà più memoria degli altri metodi in LSO-LSL.
  • Dall'8 agosto 2009 il settimo metodo restituisce il miglior valore per risparmiare in LSO-LSL.
    • Il settimo metodo è migliore del quarto metodo perché il settimo richiede una minor congestione dello script.
    • Uno script di prova col settimo metodo, una volta compilato ha avuto una memoria iniziale di 15878, mentre col quarto metodo ha avuto una memoria di 15871. Come risultato, il settimo metodo ha avuto più memoria libera del quarto alla fine dell'operazione di prova.
  • I metodi 2 e 3 compilano nella stessa cosa.
  • I metodi 5 e 6 compilano nella stessa cosa.
  • I metodi 5, 6 e 7 consentono un risparmio bytecode rispetto ai metodi 2, 3 e 4 rispettivamente, sebbene esista un bug VM LSO-LSL che provoca un malfunzionamento nelle trasformazioni in stringhe e chiavi: SVC-1710.
  • I metodi 4 e 7 possono portare a considerevoli risparmi di memoria in LSO-LSL rispetto ai metodi 2, 3, 5 e 6 (aiutano a ridurre la frammentazione cumulativa, che altrimenti risulterebbe in blocchi inutilizzabili di memoria cumulativa)[1]. In Mono-LSL non fornisce vantaggi o svantaggi significativi di memoria.
    • Dipendentemente dalla situazione (in LSO-LSL) questo metodo potrebbe non fornire alcun vantaggio. Se siete in dubbio, sagomate lo script usando e non usando questo metodo.

Unire le liste (ossia la concatenazione)

Le liste possono essere unite semplicemente usando il segno + :

<lsl>nuovalista = lista01 + lista02;

nuovalista = lista01 + ["rosso","marrone",<0,0,0>];</lsl>

Nota: l'esempio di cui sopra, nei fatti crea 3 liste nella memoria mentre il comando viene eseguito, sebbene ne venga restituita soltanto una. Ciò potrebbe influire sull'uso della memoria.

Svuotare una lista

Per svuotare una lista, impostatela per essere uguale a due parentesi quadre vuote, in questo modo:

<lsl>miaLista = [];</lsl>

Passare una lista in una funzione

Passare una lista in una funzione è un po' differente dal passare qualunque altro tipo di dato, comunque, ci sono alcuni casi utili di cui essere al corrente:

<lsl>miaLista = llListReplaceList(miaLista, ["miaStringa"], 2, 2);</lsl>

Nel codice qui sopra, chiamiamo llListReplaceList(), un'operazione abbastanza innocente, comunque, a causa del modo in cui si passano le liste, e di come funzionano le funzioni come llListReplaceList(), llDeleteSubList(), llList2List() e llListSortList() (e altre), potete finire con l'usare due, tre o persino quattro volte l'ammontare di memoria richiesto per immagazzinare la vostra lista, solo chiamando quella funzione! Per evitare questo problema, possiamo utilizzare un po' di ottimizzazione; se sapete che la lista che state passando in questa funzione non verrà mai più letta (ad esempio se il risultato della funzione sovrascriverà la lista) allora possiamo fare questo:

<lsl>miaLista = llListReplaceList((miaLista = []) + miaLista, ["miaStringa"], 2, 2);</lsl>

L'effetto di ciò è di ridurre enormemente l'utilizzo della memoria, in entrambe le VM LSO-LSL e Mono, e ridurrà anche la frammentazione della memoria. Questo funziona anche in altri casi che non siano chiamate a funzioni, per esempio quando si concatenano le liste (vedi sopra), potreste scoprire che questo sistema elimina quasi completamente qualsiasi problema di memoria:

<lsl>list lista1 = ["a", "b", "c"]; lista2 = ["d", "e", "f"]; lista3 = (lista1 = lista2 = []) + lista1 + lista2;</lsl>

Processing a List Into Another List

A more complex case, but sometimes when processing a large list you may find that you are producing a similarly large list as a result. In such cases there is a very large risk of running out of memory. As a result, in any case where you know you will, or might, be working on a particularly large list, it will often be worth manipulating them similarly to:

<lsl>list myOutput = [];

integer i = 0; integer x = myList != []; for (; i < x; ++i) {

   if (i > 10) { // Prune list every 10 elements
       myList = llDeleteSubList((myList = []) + myList, 0, i - 1);
       x -= i;
       i = 0;
  }
  // Do some work here:
  myOutput += llList2List(myList, i, i); // A silly bit of example work

}</lsl>

This method (deleting every few list entries or strides) is preferable to deleting an entry every loop, as the cost of calling llDeleteSubList() is very high. It is up to the scripter to decide what their optimal chunk-size is for pruning an input list, as you will need to balance memory use with delete cost.

Strided lists

One common use of lists is to duplicate the functionality of structured collections of data (aka structs). Such collections, available in many programming languages, are absent from LSL.

In-world in SL, (still as of July 2008), a strided list is the closest you can get to storing limited amounts of data in some kind of structure that you can access and manipulate in a few, limited ways.

Strided lists allow you to store related data pieces grouped (aka "strided") in sets. You can determine how many pieces of data in each "grouping."

An example is best at this point. You might use a strided list to track the names, gender and rez dates of a group of avatars:

<lsl>list demographics = ["John Adams", "male", "2007-06-22", "Shirley Bassey", "female", "2005-11-02", "Matt Damon", "male", "2008-05-19"];</lsl>

This example has a stride of three, because each grouping (or stride) has three data elements. Index 0 ("John Adams") is the start of the first instance (because list counting starts a 0), index 3 ("Shirley Bassey") is the start of the second instance, and so on.

It is important that the pieces of information in each grouping are always entered in the same sequence for every instance of the grouping in the list! In the example above, this means that the name needs to be always the first of the three related elements. You should consider carefully the order in which you record information because the function to sort a list, llListSort, will only sort on the first element of the instances. In other words, if the avatar's rez date were the most important attribute for your script, then you would need to record it first, and the name second. If you wish to be able to sort by avatar last name rather than first name, the name should be added to the list in Lastname FirstName format (avoiding a comma, though, of course, unless you wanted LastName and FirstName treated as separate elements in the list.)

To add another person to the above list, you would do this:

<lsl>demographics += ["Dorthy Lamour", "female", "2010-01-22"];</lsl>


You cannot do any kind of fancy data analysis or manipulation with strided lists, as you can in off-world databases or spreadsheets, but they can meet some limited, in-world needs, if you don't have the resources to tie-in off-world tools. It should be noted that when manipulating extremely large strided lists, that if you expect to be editing the lists that you may wish to use one list for each "column", this may be more complex but significantly reduces the amount of memory required when manipulating the lists, though it will be a lot more difficult to sort.

Here are the tools we do have for strided lists:


The following three (as of July 2008) native LSL functions can be used with strided lists:


Here are some additional, user-created functions for working with strided lists:

function purpose
ListStridedMove Moves something in a strided list to another place in the strided list.
ListStridedRemove Removes part of a strided list.
ListStridedUpdate Updates part of a strided list.

Extended List Operations

These functions have been created and contributed by LSL users to perform operations not covered by built-in LSL functions.


function purpose
ListCast Processes a list so that its contents are of a single-type.
List_cast Processes a list so that its contents are converted from strings to their respective types.
ListCompare Compares two lists for equality
ListItemDelete Removes one element from a list.
ListKeyCase Changes the values of the whole list into uppercase or lowercase based on input
ListToWholeNumbers Given a list of floats, converts them all to whole numbers (aka integers.)
ListXorY Join two lists to make one new combined list, while also eliminating any resulting duplicates in the new list.
ListXandY This function examines two lists, and returns a new list composed of the elements that both lists have in common.
ListXnotY Show what x list has that y list is missing.
ListXxorY Returns a new list, composed of elements that were in either original script, but not both. Note: This is not the same as getting rid duplicates by preserving just one of each duplicated item. It goes further, and removes both items.
ListXequY Answers the question: is list X identical to list Y?
ListXneqY Answers the question: is list X different from list Y?
Replace Replaces a single occurrence of something in a list with something else that you specify.
Replace All Replaces all occurrences of 'from list' with those in 'to list' in 'src list'. Not as concise as the replace function above, but will handle multiple items at the same time.
ListUnique Given a list of elements, returns a list of only the unique individual elements in that list.
ccFixListDatatypes Walks a list, casts the elements to the appropriate types, and returns a fixed list. Useful for things like llSetPrimitiveParams when you've parsed your data out of a string.
2D Pseudo-Array A way to emulate the behavior of a 2 dimensional array.

This category currently contains no pages or media.