Difference between revisions of "User:Kireji Haiku/How to deal with lists in LSL"

From Second Life Wiki
Jump to navigation Jump to search
m
Line 1: Line 1:
NOTE: Firstly look to see if there is a [[:Category:LSL_Functions|built-in function]] available to process your list the way you wish. This will always be faster than coding your own loops.
e.g. [[llListFindList]](), [[llListStatistics]]()
This page is more about different ways to code loops, rather than about processing lists.
==How to deal with lists in the Linden Scripting Language:==
==How to deal with lists in the Linden Scripting Language:==


<div id="box">
<div id="box">
==the basics==
==the basics==
NOTE: Firstly look to see if there is an ll function available to process your list the way you wish. This will always be faster than coding your own loops.
e.g. llListFindList(), llListStatistics()
This page is more about different ways to code loops, rather than about processing lists.


<div style="padding: 0.5em">
<div style="padding: 0.5em">
Usual list with 10 items:
Usual [[List]] with 10 items:


<lsl>
<lsl>
Line 15: Line 17:
</lsl>
</lsl>


Then start with a for-loop:
Then start with a [[for]]-loop:


<lsl>
<lsl>
Line 39: Line 41:
</lsl>
</lsl>


Setting the default value to 0 is redundant, too, since LSL initializes integers as 0. Keep in mind that other languages may not do this.
Setting the default value to 0 is redundant, too, since LSL initializes [[Integer|integers]] as 0. Keep in mind that other languages may not do this.


<lsl>
<lsl>
Line 51: Line 53:
</lsl>
</lsl>


 
Calculating the list length every step is redundant too because the length doesn't change - at least in the example demonstrated here.
Calculating the list length every step is redundant too because the length doesn't change.


<lsl>
<lsl>
Line 72: Line 73:
Now the index for items in a list of ten is either:
Now the index for items in a list of ten is either:


<pre>
{| width="100%" {{Prettytable}}
0123456789
|- {{Hl2}}
 
! '''plain English'''
//  or
! '''using positive indices'''
! '''using negative indices'''
|-
||first item of a list of ten
||0
||-10
|-
||second item of a list of ten
||1
||-9
|-
||third item of a list of ten
||2
||-8
|-
||fourth item of a list of ten
||3
||-7
|-
||fifth item of a list of ten
||4
||-6
|-
||sixth item of a list of ten
||5
||-5
|-
||seventh item of a list of ten
||6
||-4
|-
||eight item of a list of ten
||7
||-3
|-
||ninth item of a list of ten
||8
||-2
|-
||tenth item of a list of ten
||9
||-1
|}


-10, -9, -8, -7, -6, -5, -4, -3, -2, -1
While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See [[LSL_Hacks]] for more details.
</pre>
 
Note: ++index is fractionally faster than index++ in LSO, but using the preferred Mono VM, there is no timing difference. (I obtained identical timings over 70 million iteration. OQ).


We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:
We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:
Line 112: Line 152:
|}
|}


Now trying to simplify the math for calculating the index default value we can use '''bitwise-NOT of the length''' which is the same as the negative length minus one:
Now trying to simplify the math for calculating the index default value we can make use of the [[LSL_Operators]] and initialize with '''bitwise-NOT of the length''' which is the same as <code>-1*length - 1</code> or the negative length minus one:


{| class="sortable" width="100%" {{Prettytable}}
{| class="sortable" width="100%" {{Prettytable}}
Line 123: Line 163:
integer lengthOfList = llGetListLength(listOfTenItems);
integer lengthOfList = llGetListLength(listOfTenItems);


//  it's bitwise-NOT (~) not minus (-)
//  it's bitwise-NOT (~) instead of minus (-)
integer index = ~lengthOfList;
integer index = ~lengthOfList;
for (;index < 0;++index)
for (;index < 0;++index)
Line 153: Line 193:
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];


//  it's bitwise-NOT (~) not minus (-)
//  it's bitwise-NOT (~) instead of minus (-)
integer index = ~llGetListLength(listOfTenItems);
integer index = ~llGetListLength(listOfTenItems);
for (;index < 0;++index)
for (;index < 0;++index)
Line 183: Line 223:
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];


//  it's bitwise-NOT (~) not minus (-)
//  it's bitwise-NOT (~) instead of minus (-)
integer index = ~llGetListLength(listOfTenItems);
integer index = ~llGetListLength(listOfTenItems);
for (;index;++index)
for (;index;++index)
Line 203: Line 243:
|}
|}


and improve readability by using a while-loop:
and improve readability by using a [[while]]-loop:


{| class="sortable" width="100%" {{Prettytable}}
{| class="sortable" width="100%" {{Prettytable}}
Line 213: Line 253:
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];


//  it's bitwise-NOT (~) not minus (-)
//  it's bitwise-NOT (~) instead of minus (-)
integer index = ~llGetListLength(listOfTenItems);
integer index = ~llGetListLength(listOfTenItems);
while (++index)
while (++index)
Line 236: Line 276:
</div>
</div>
<div id="box">
<div id="box">
==finally clean code==
==finally clean code==
<div style="padding: 0.5em">
<div style="padding: 0.5em">
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:
{| class="sortable" width="100%" {{Prettytable}}
{| class="sortable" width="100%" {{Prettytable}}
|- {{Hl2}}
|- {{Hl2}}

Revision as of 05:23, 4 August 2014

NOTE: Firstly look to see if there is a built-in function available to process your list the way you wish. This will always be faster than coding your own loops. e.g. llListFindList(), llListStatistics()

This page is more about different ways to code loops, rather than about processing lists.

How to deal with lists in the Linden Scripting Language:

the basics

Usual List with 10 items:

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; </lsl>

Then start with a for-loop:

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

integer index = 0; for (index = 0;index < llGetListLength(listOfTenItems);index++) {

   //do something

} </lsl>

Resetting the value to 0 for index was redundant so we can skip that:

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

integer index = 0; for (;index < llGetListLength(listOfTenItems);index++) {

   //do something

} </lsl>

Setting the default value to 0 is redundant, too, since LSL initializes integers as 0. Keep in mind that other languages may not do this.

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

integer index; for (;index < llGetListLength(listOfTenItems);index++) {

   //do something

} </lsl>

Calculating the list length every step is redundant too because the length doesn't change - at least in the example demonstrated here.

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index; for (;index < lengthOfList;index++) {

   //do something

} </lsl>

slightly more advanced now

Now the index for items in a list of ten is either:

plain English using positive indices using negative indices
first item of a list of ten 0 -10
second item of a list of ten 1 -9
third item of a list of ten 2 -8
fourth item of a list of ten 3 -7
fifth item of a list of ten 4 -6
sixth item of a list of ten 5 -5
seventh item of a list of ten 6 -4
eight item of a list of ten 7 -3
ninth item of a list of ten 8 -2
tenth item of a list of ten 9 -1

While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See LSL_Hacks for more details.

We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index = -lengthOfList - 1; for (;index < 0;++index) {

   //do something

} </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index; // pay attention here! index is 0 before loop starts and for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round {

   //do something

} </lsl>

Now trying to simplify the math for calculating the index default value we can make use of the LSL_Operators and initialize with bitwise-NOT of the length which is the same as -1*length - 1 or the negative length minus one:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

// it's bitwise-NOT (~) instead of minus (-) integer index = ~lengthOfList; for (;index < 0;++index) {

   //do something

} </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index; // pay attention here! index is 0 before loop starts and for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round {

   //do something

} </lsl>

as you might have seen by now, we can merge two lines in the middle:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

// it's bitwise-NOT (~) instead of minus (-) integer index = ~llGetListLength(listOfTenItems); for (;index < 0;++index) {

   //do something

} </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);


integer index; // pay attention here! index is 0 before loop starts and for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round {

   //do something

} </lsl>

and because index should have a negative value while looping and the loop stops when index reaches zero, we can change the code to:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

// it's bitwise-NOT (~) instead of minus (-) integer index = ~llGetListLength(listOfTenItems); for (;index;++index) {

   //do something

} </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index; // pay attention here! index is 0 before loop starts and for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round {

   //do something

} </lsl>

and improve readability by using a while-loop:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

// it's bitwise-NOT (~) instead of minus (-) integer index = ~llGetListLength(listOfTenItems); while (++index) {

   //do something

} </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index = -1;// attention again! index is -1 before the first round // each round index is incremented FIRST before being compared to lengthOfList and then used within the loop while (++index < lengthOfList) {

   //do something

} </lsl>

finally clean code

and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:

if indexes can be negative if indexes can NOT be negative
<lsl>

list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

// negative length now! integer index = -llGetListLength(listOfTenItems);

do {

   //do something

} while (++index); </lsl>

<lsl> list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; integer lengthOfList = llGetListLength(listOfTenItems);

integer index; do {

   //do something

} while (++index < lengthOfList); </lsl>