I’m curious why the commented out statements in the code below do not work.
local lst1, lst2;
lst1 = [0, 1, 2, 3];
"The length of lst1 is <<lst1.length>>.\n";
lst1 = lst1 + [4, 5, 0];
"The length of lst1 is <<lst1.length>>.\n";
lst2 = ['Tatiana', 'Emily', 'Debbie'].length();
"The length of lst2 is <<lst2>>.\n";
"Count of 0 in lst1: <<lst1.countOf(0)>>.\n";
// The statements below cannot be executed.
// Error: Runtime error: object value required
//local debCount = lst2.countOf('Debbie');
//local name = 'Debbie';
//"Count of 'Debbie' in lst2: <<lst2.countOf(name)>>.\n";
//"Items in lst2: "; lst2.forEach(new function(item) { "<<item>> "; }); "\n";
No, you can do everything that you were doing. You just made a small error in your declaration.
lst2 = ['Tatiana', 'Emily', 'Debbie'].length();
"The length of lst2 is <<lst2>>.\n";
Clearly, this defines “lst2” not as a list, but as the length of a list (which is never recorded into any variable).
When you later try to work with the “lst2” variable as if it were a list, you are in fact working with an integer variable of value 3, since this is the length of the [list] that you set lst2 equal to.
Use instead
lst2 = ['Tatiana', 'Emily', 'Debbie'];
"The length of lst2 is <<lst2.length()>>.\n";
For your declaration and reporting, and you’ll find the rest of the code works as you anticipate.
You can modify lists, but it always creates a new list, leaving the original unchanged. If you want to capture the result of that modification, you have to assign it to a local, property, or some other means of reference.
Here you’ve replaced the contents of the lst1 local with the modified list. The original list is still out there, floating in memory, but it can no longer be referred to and the garbage collector will eventually sweep it up.
Most of what applies to lists also applies to strings - they’re both immutable and both somewhat privileged in terms of the underlying VM. Obviously you can do a lot with strings, and the same is true of lists.
The main thing you can’t do is in-place modification. This gets me most often with strings, where I run a regex or replace part of a string and expect to retain that value without an assignment, which doesn’t work.
Related to that is that both have a counterpart class - Vector, StringBuffer - where you can do in-place modification. This is helpful when building a list or string out of lots of little units, since you don’t create an entire VM object whenever you append something. These can be converted back to the static kind when you finish.
Other than that, I don’t see a lot of limitations. I use lists extensively.
You can do both. In the iteration case, it’s better to build it as a vector, then convert the vector to a list.
local lst = new Vector(50);
forEachInstance(Room, {room: lst.append(room)});
lst = lst.toList();
Lists and functions work very well together. A common pattern is to start with a list and filter it through many different functions (or recursively through the same function) before returning a value.