Don't click here unless you want to be banned.

LSL Wiki : list

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawling22.us.archive.org

List

Instead of arrays, LSL uses lists. The list type is exactly what it sounds like: a heterogeneous list of the other data types. Lists are created via comma-separated values (CSV) of the other data types. enclosed by square brackets: "[" and "]". See below for examples of the syntax.

Lists not only store the value of the list item, but also its type (see llGetListEntryType and llCSV2List). To directly enter a float value into a list, a decimal point (.) must be used.

Because they store multiple value types, lists are not accessed with square brackets like arrays are. They are read by accessor functions that specify the type of value attempting to be retrieved (e.g. llList2Integer) and written with accessor functions that insert or replace values (or ranges of values) based on new list variables (e.g. llListReplaceList).

Note: while the LSL compiler will only accept code with a maximum of 72 items in a list, lists can actually support as many items as a script's memory will allow. If a list of more than 72 predefined items is needed, just concatenate (combine) two predefined lists into a new one: longlist = firstpart + secondpart;

Lists cannot contain other lists, so using them like a multidimensional array is not possible natively (although several ways around this are available, notably this script). Also, strided lists can be used.

Example:
//a list with a string, integer, float, vector and rotation
list l = ["somestring",12,3.0,<3.3,4,0>,<0,0,0,1>];

Lists can be concatenated by using +.
Example:
newlist = oldlist + ["oneitem","anotheritem"];

Thus, to add an element to the (end) of an existing list:
Example:
myList = myList + [new_item];

or

myList += [new_item];

This voodoo magic will allow appending new elements in a memory efficient fashion (thanks to BlindWanderer):
myList = (myList=[]) + myList + ["new_item"];
Don't ask me why but I can save 3-4KB of memory with adding 90 elements. - PsykePhaeton Is this broken as of Aug-21-2007? It doesn't appear to work - VagnerSousaBR "This voodoo magic seems to work fine. Just pay attention to the "new_item" square brackets when it's already returned as a list type in a function like llParseString2List(). I got a stack-heap collision error when I was composing an huge list by the usual way. This way has worked fine."


To clear a list, set it equal to nothing:
Example:
myList = [];

To search a list for a value, use llListFindList
list myList = ["A","B","C","D","E","F"];
string searchFor = "C";

integer index = llListFindList( myList, [searchFor] );

if ( index != -1 )
    llOwnerSay( searchFor + " was found in myList at position " + (string)index );
else
    llOwnerSay( searchFor + " was not found in myList" );

Refer to a list's elements by their index number. Lists have 0-based indexing, where the first element has index 0.
Example:
list myList = ["A","B","C"];
string element;

element = llList2String(myList,0);
// element now has the value "A".

element = llList2String(myList,1);
// element now has the value "B".

element = llList2String(myList,2);
// element now has the value "C".

The value llGetListLength() returns the number of elements in the list. Therefore, the last element has index = (llGetListLength(myList) - 1).
Example:
list myList = ["A","B","C"];
integer listLength = llGetListLength(myList);
// listLength equals 3.

string element = llList2String(myList,listLength);
// myList doesnt have an element at index 3 - this will return an empty string.

string element = llList2String(myList,listLength - 1);
// element now has the value "C".

Negative numbers can also be used to count backwards in a list. Therefore, the last element has index -1. The first element would also have an index of (-llGetListLength(myList))
Example:
list myList = ["A","B","C"];
integer listLength = llGetListLength(myList);
// listLength equals 3.

string element = llList2String(myList,-listLength);
// element now has the value "A".

string element = llList2String(myList,-1);
// element now has the value "C".

Functions

Function Name Purpose
llGetListLength Gets the number of elements in a list
llCSV2List Converts comma-separated values (CSV) to a list
llList2CSV Converts a list to comma-separated values (CSV)
llDeleteSubList Removes a portion of a list
llList2List Returns a portion of a list
llListFindList Returns the position (index) of the first instance of a sublist in a list
llListInsertList Inserts a list into a list
llListReplaceList Replaces a part of a list with another list
llDumpList2String Dumps a list to a string with a specified separating string
llParseString2List Parses a string to a list, using two lists of separators
llParseStringKeepNulls Similar to llParseString2List, but adds null values between spaces
llList2ListStrided Extracts a subset of a strided list
llListSort Sorts a list ascending or descending, as appropriate to type.
llListStatistics Performs statistical operations on a list composed of integers and floats.
llListRandomize Randomizes a list
llGetListEntryType Gets the type of entry of an element in list
llList2Float Returns the float element
llList2Integer Returns the integer element
llList2Key Returns the key element
llList2Rot Returns the rotation element
llList2String Returns the string element
llList2Vector Returns the vector element

Strided Lists

Since lists cannot contain items of the list type, the only way to get something similar to a multidimensional array is using strides. A strided list is a regular list with items grouped together in a fixed layout.

Say you wanted to make a visitor tracker and keep track of visitor's names, time spent on your land, and the date they visited last. You'd use a strided list, where each stride consists of three items:

integer STRIDELENGTH = 3; // this is very helpful when dealing with strided lists to keep your code flexible
list visitors = ["Ama Omega", 5, "2004-06-12", "Catherine Omega", 12, "2004-06-28", "Ezhar Fairlight", 25, "2004-06-30"];
//

Whenever you manipulate this list, you do it in complete strides, so to add another visitor to the list:
visitors += ["Mistress Midnight", 1, "2004-06-30"];

To sort the list by names in ascending order:
visitors = llListSort(visitors, STRIDELENGTH, TRUE);

To remove one stride from the list:
list DeleteSubListStrided(list src, integer start, integer end, integer stride) {
    return llDeleteSubList(src, start * stride, (end * stride) + stride - 1);
}

visitors = DeleteSubListStrided(visitors, 0, 0, STRIDELENGTH);

To replace a stride in the list:
list UpdateSubListStrided(list src, list stride, integer start, integer len) {
    return llListReplaceList(src, stride, start, len-1);
}

The following functions have direct support for strided lists:

More examples of functions dealing with strided lists can be found on this page. LibraryStridedLists

Q & A


Q: Does this function have O(1) time? I want to use it a lot on some big lists.
A: No, it takes much longer with growing list size. Better get used to LSL being painfully slow when manipulating large data sets (strings by far being the worst).
Re-Question: So, does that mean llListInsertList and llDeleteSubList actually make copies, i.e., reallocate, the entire list they're operating on?
Re-Answer: Yup. LSL is a pass-by-value language. Any information passed to a function is copied to that function's stack-frame before the function is run. This means that in practical terms, you need twice as much memory to insert or delete a sublist. (See the notes on the llListInsertList and llDeleteSubList pages to eliminate some confusion about the "manipulation" they do.)

Q: Why are there so many llList2* functions?
A: LSL2 doesn't support run-time typing, meaning you have to actually specify the type of each variable. The Lindens could have implemented a single function, llList2String, then required explicit typecasting, as in (integer)llList2String(foo, 0). However, that isn't as memory- or CPU-efficient as llList2Integer(foo,0) (yes, really) and the amount of work required for the Lindens to implement seperate functions for each type was negligible.
You can still typecast values stored in a list, of course, but it's advised to use the llList2* functions, unless it's a vector or rotation stored as a string, in which case you should cast to a vector or rotation after using llList2String. llList2Vector and llList2Rotation do not cast from strings automatically. See the next question for more.

Q: Have the old problems concerning the odd behavior of llList2Vector and llList2Rot when requesting a TYPE_STRING element from the list been fixed yet?
A: No. If a list element is a string containing text that would otherwise be directly typecast to a vector or rotation, It will not be converted. The resulting vector or rotation will be ZERO_VECTOR or ZERO_ROTATION respectively. This is a bug. To get around it, use llList2String to retrieve elements from your list, then cast them to vectors or rotations as needed: (vector)llList2String(positions,2);

Lists can be conveniently passed as a single string using the CSV functions. For example, this is useful for sending complex data between objects via listen or within linked objects with llMessageLinked. Or not, if you would be passing data with vectors, rotations, or strings with commas. llDumpList2String and llParseString2List are recommended for safe passing of lists. For an example of this method see ExampleListConversion.


Functions | Types
There are 12 comments on this page. [Display comments/form]