List
"List" is a native TADS 3 datatype. Lists are actually instances
of the intrinsic class List, which means that you can call methods
defined by the List intrinsic class on list objects.
Value Semantics
Lists have "value semantics," which means that a given list value
is immutable. Any operation that appears to modify a list value is
actually creating a new list value, and leaving the original value
unchanged. This behavior makes it very easy to work with lists,
because you never have to worry about how many variables or properties
refer to a list - even if several variables refer to a list value,
each variable effectively has its own private copy of the list, so
changes made to one variable's list won't affect any others. This
also means that you can pass a list to a function without having to
worry about whether the function will modify the list, and similarly
that you can modify a list passed in as an argument to your functions
without having to worry about how the changes will affect the caller.
This is discussed in more detail in the Vector
class section.
List iterations
A List is a subclass of Collection, so
you can use the createIterator() method to create an Iterator to
iterate over the elements of the list. The Iterator that a List
creates is called an IndexedIterator, and visits the elements of the
list in index order (the first element visited is the element at index
1, the second is the element at index 2, and so forth).
List methods
List is a subclass of Collection, and
thus defines the Collection methods. In addition, List defines the
methods shown below.
append(val)
Appends the value
val to this list, returning the resulting
list. This is almost the same as using the
+ operator to append
val to the list, but differs in that this method always treats
val as a single new element, even if
val is a list.
Consider the following:
local x = [1, 2, 3];
local y = x + [4, 5];
local z = x.append([4, 5]);
In this example, the value of y is the list [1, 2, 3, 4, 5]:
if the value on the right of a + operator is a list, the + operator
appends each value of the list as a separate element. In contrast,
the value of z is [1, 2, 3, [4, 5]], because the append() method
always treats its argument as a single element of the new list.
Note that you can achieve the same effect using the + operator by
constructing a new list for the right operand:
This will ensure that the value of y2 is the same as the value of
z: [1, 2, 3, [4, 5]]. However, the append() method is more efficient
than constructing a new list for the right operand of +, because it's
not necessary to construct the intermediate list using append().
appendUnique(lst)
Appends the elements of the list lst to this list, returning a
new list consisting only of the unique elements of the combination.
Each value appearing in the result list will appear in the result list
only once. (The same effect could be obtained by concatenating the
two lists with the + operator then applying getUnique() to the
result, but this method is more efficient because it avoids
constructing the fully concatenated list as an intermediate value.)
car()
Returns the first element of the list. If the list has no elements,
returns
nil.
(The names "car" and "cdr" are historical; they come from the Lisp
programming language, which borrowed them from an old IBM mainframe
instruction set.)
cdr()
Returns the "tail" of the list; that is, the rest of the list after
removing the first element. If the list has no elements, returns
nil.
This function is almost the same as
sublist(2), except that
sublist()
would return an empty list if given an empty list, whereas
cdr()
returns
nil in this case.
(The names "car" and "cdr" are historical; they come from the Lisp
programming language, which borrowed them from an old IBM mainframe
instruction set.)
countOf(val)
Returns the number of elements whose values equal val.
countWhich(cond)
Returns the number of elements for which the callback function
cond returns a non-false value (anything but nil or 0). For
each element, this method calls the callback, passing the current
element as the argument. If the callback returns anything but nil or
0, the method counts the element. After invoking the callback for
each element, the method returns the resulting count.
indexOf(val)
Returns the index of the first element of the list equal to the given
value. If val does not appear anywhere in the list, the method
returns nil. The first element is at index 1.
indexWhich(cond)
Finds the first element for which the given condition is true. The
method iterates through the elements of the list, starting at the
first element and proceeding in order, and applies the callback
function cond to each element. The callback takes one
argument, which is the value of the list element, and returns a
condition result value. For each element, if the callback function
returns a non-false value (i.e., any value except nil or 0), the
method immediately stops the iteration and returns the index of that
element. If the callback returns a false value (nil or 0) for
every element of the list, the method returns nil.
forEach(func)
Invokes the callback function (func)(value) for each element, in
order from first to last, passing the value of one element as
value to the callback on each invocation. The callback
function takes one argument, which is the current element, and returns
no value. This method returns no value. This method is a convenient
means of executing some code for each element of the list.
forEachAssoc(func)
Invokes the callback function (func)(index, value) for each
element, in order from first to last, passing each element's index and
value to the function func. The callback function returns no
value. This method returns no value. This method is a convenient
means of executing some code for each element of the list; unlike
forEach(), this method provides its callback with the index as well as
the value for each element it visits.
getUnique()
Returns a new list consisting of the unique elements of the original
list. For each value in the original list, the value will appear in
the new list only once. The order of the elements in the new list is
that of the first appearances of the unique elements of the original
list. For example, if the original list is [1, 5, 2, 5, 3, 5, 4, 5],
this method will return [1, 5, 2, 3, 4].
insertAt(index, val1, val2, …)
Returns a new list which results from inserting the given values
(
val1,
val2, and so on) into the existing list before
the element at the position given by
index. At least one value
argument is required; if multiple value arguments are provided, the
values are inserted into the list in the same order in which they
appear in the arguments.
If index is 1, the values are inserted before the first
element of the existing list (this means that insertAt(1, x) is
equivalent to prepend(x)), and if index is equal to the
number of elements in the original list plus 1, the values are
inserted after the last element of the existing list (so
lst.insertAt(lst.length() + 1, x) is equivalent to
lst.append(x)). An index value less than 1 or greater than the
number of elements in the list plus 1 is illegal and results in an
"index out of range" exception.
Because the new elements are inserted before any existing element
at the insertion point, the index in the result list of the first
element inserted always equals index. For example, consider
this statement:
lst = lst.insertAt(5, 'a', 'b', 'c');
After this statement is executed, lst[5] will be 'a'.
Note that, if any of the values to be inserted are themselves
lists, each one is inserted as a single list-valued element, in the
same manner as append(val) and prepend(val).
intersect(lst2)
Returns a new list consisting of the intersection of this list and
lst2; that is, a list consisting of the elements common to both
this list and lst2. lst2 must also be a list. If the
two lists have no elements in common, the result is an empty list. If
an element of the shorter list (or, if the lists are of equal length,
this list) appears more than once in the shorter list, and that
element value also appears in the longer list, then the element will
be in the result list the same number of times that it is in the
shorter list. An element repeated in the longer list will not be
repeated in the result list.
lastIndexOf(val)
Returns the index of the last element in the list whose value equals
val. If no element in the list equals val, this method
returns nil.
lastIndexWhich(cond)
Returns the index of the last element in the list for which the
callback function cond returns a non-false value (anything
except nil or 0). This method is similar to indexWhich(cond),
but scans the list in reverse order, starting at the last element and
working towards the first. Returns nil if the callback returns
nil or 0 for every element.
lastValWhich(cond)
Returns the value of the last element in the list for which the
callback function cond returns a non-false value. This method
is similar to lastIndexWhich(cond), but returns the value of the
matching element rather than its index. Returns nil if the callback
returns nil or 0 for every element.
length()
Returns the number of elements in the list.
mapAll(func)
For each element of the list, this method invokes the callback
function
func, passing the current element as the single
argument, then adds the callback's return value to a new list. The method
returns the resulting new list, which has the same number of elements
as the original list. Each element of the returned list contains the
result returned by func for the corresponding element of the original
list. This method does not modify the original list, but creates a
new list.
Here's an example that creates a new list consisting of multiplying
each element of an original list by 2 (naturally, for this to work,
the original list must consist entirely of integer values):
x = [1, 2, 3, 4];
y = x.applyAll({x: x*2});
prepend(val)
Returns a new list which results from inserting the value val
before the first element of the existing list. This method is similar
to append(val), but this method inserts the new element at the
beginning of the list rather than at the end. Note that if val
is a list, it is prepended as a single list-valued element.
removeElementAt(index)
Returns a new list which results from deleting the element at the
given index. For example, [100, 200, 300].removeElementAt(2)
yields [100, 300]. The index value must be at least 1 and
at most the number of elements in the list; if index is outside
this range, the method throws an "index out of range" exception.
removeRange(startIndex, endIndex)
Returns a new list which results from deleting the elements starting
at
startIndex and ending with (and including)
endIndex.
If
endIndex equals
startIndex, only one value is
deleted, so
removeRange(x, x) is equivalent to
removeElementAt(x).
Both index values startIndex and endIndex must be at
least 1 and at most the number of elements in the list, and
endIndex must be greater than or equal to startIndex;
the method throws an "index out of range" exception if these
conditions are not met.
sort(descending?, comparisonFunction?)
Returns a new list consisting of the elements of this list rearranged
into a sorted order. By default, this method sorts the elements of
the list into ascending order, but you can reverse this ordering by
specifying
true for the
descending parameter.
The optional comparisonFunction can be used to specify the
ordering of the result. If this argument is not specified (or is
nil), the method will sort the elements according to the standard
system ordering of values; hence, the elements must be of comparable
types (such as all integers or all strings). By specifying a
comparison function, you can provide your own special ordering, and
you can also sort values that have no system-defined order, such as
object values.
If provided, the comparisonFunction value is a pointer to a
function taking two arguments, which are two values from the list to
be compared. The function returns an integer less than zero if the
first value is less than the first, zero if the two values are equal,
or an integer greater than zero if the first value is greater than the
second.
For example, if you wanted to sort a list of objects so that the
objects are placed into descending order of their "priority" property
values, where the "priority" property has an integer value, you could
do this:
lst = [obj1, obj2, obj3];
sortedLst = lst.sort(true, { a, b: a.priority - b.priority });
sublist(start, length?)
Creates and returns a new list consisting of a sublist of this list
starting at the element of this list at index
start, and
continuing for the number of elements given by
length, if
present, or to the end of this list if not. Examples:
[1, 2, 3].sublist(2) yields [2, 3]
[1, 2, 3].sublist(2, 1) yields [2]
subset(func)
Creates and returns a new list containing the elements of this list
for which the callback function
func returns true (i.e., any
value other than
nil or 0). For each element of the
source list, this method invokes the callback function, passing the
value of the current element as the callback function's single
argument. If the callback returns
nil or 0, the
method omits the element from the result; otherwise, the method
includes the element in the result list. The new list's elements will
be in the same order as the selected elements from the source list.
This method does not modify the original list.
This example uses a short-form anonymous function to create a new
list that contains only the elements from an original list whose
values are greater than 10.
x = [5, 10, 15, 20];
y = x.subset({x: x > 10});
valWhich(cond)
Returns the value of the first element for which the callback function
cond returns non-false (i.e., anything except nil or 0).
This method is similar to indexWhich(cond), but returns the value
of the first matching element rather than its index. If cond
returns nil or 0 for every element of the list, this method returns
nil.