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.
String conversions
String conversions
A list can be converted to a string using the toString() function. A list can also be used in a context where a non-string value is implicitly converted to a string, such as on the right-hand side of a "+" operator where the left-hand side is a string.
The string conversion of a list consists of the list's elements, each itself first converted to a string if necessary, concatenated together, with commas separating elements. For example, toString([1, 2, 3]) yields the string '1,2,3'.
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.
The adv3Lite library defines a number of additional methods on the List class. Although these sre not strictly part of the intrinsic List class they are included here for the convenience of adv3Lite users, and marked [a3L].
append(val)
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:
local y2 = x + [[4, 5]];
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)
car()
(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()
(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)
countWhich(cond)
element(i) [a3L]
nil
otherwise
(i.e., if I is out of range for this List).
find(ele) [a3L]
indexOf(ele)
.
forEach(func)
forEachAssoc(func)
generate(func, n)
Creates a new list containing n elements by invoking the callback function func once for each element, and using the return value as the element value. This is a class method that you call on the List class directly, as in List.generate(f, 10).
func is a callback function, which can be a regular function or an anonymous function. func can take zero or one argument. The one-argument form is invoked with the index of the current element as the argument on each call.
generate() is convenient for creating a list of values based on a formula. For example, this creates a list of the first ten positive even integers:
local e = List.generate({i: i*2}, 10);
That creates a list containing ten elements. Each element's value is determined by calling the anonymous function {i: i*2} with the index of that element. So the value of the first element, at index 1, is determined by calling the anonymous function with i=1. In this case the function returns i*2 == 1*2 == 2. The second element is determined by calling the function again with i=2, which returns 4, and so on for the remaining elements.
This creates a list of the first 20 Fibonacci numbers:
local a = 0, b = 1; local fib = List.generate({: local f = a, a = b, b = f + a, f }, 20);
(For a simple way of generating a list consisting of a repeated fixed value, see the makeList() function.)
getUnique()
indexOf(val)
indexOfMax(func?)
If func is specified, it must be a function pointer. The method calls func() for each element in the list, passing the element's value as the function argument. The function must return a value. The result of indexOfMax in this case is the index of the element for which func() returned the maximum value.
For example, if lst is a list of string values, lst.indexOfMax({x: x.length()}) returns the index of the longest string in the list.
indexOfMin(func?)
If func is specified, it must be a function pointer. The method calls func() for each element in the list, passing the element's value as the function argument. The function must return a value. The result of indexOfMin in this case is the index of the element for which func() returned the minimum value.
For example, if lst is a list of string values, lst.indexOfMin({x: x.length()}) returns the index of the shortest string in the list.
indexWhich(cond)
insertAt(index, val1, val2, …)
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)). If index is negative, it counts backwards from the end of the list: -1 inserts before the last element, -2 inserts before the second to last, and so on. If index is zero, elements are inserted after the existing last element.
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)
join(sep?)
Each element is converted to a string using the usual automatic conversions before it's concatenated. If an element can't be converted to string, the method throws an error.
lastIndexOf(val)
lastIndexWhich(cond)
lastValWhich(cond)
length()
mapAll(func)
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});
matchProto(proto) [a3L]
TypeXxx
type code, to
match a value of the given native type; an object class, to match
an instance of that class; 'any', to match a value of any type; or
the special value '...', to match zero or more additional
arguments. If '...' is present, it must be the last prototype
element.
maxVal(func?)
If func is specified, it must be a function pointer. The method calls func() for each element in the list, passing the element's value as the function argument. The function must return a value. The result of maxVal in this case is the value of the element which maximizes func. Note that the element value is returned, not the return value of func.
For example, if lst is a list of string values, lst.maxVal({x: x.length()}) returns the longest string in the list.
minVal(func?)
If func is specified, it must be a function pointer. The method calls func() for each element in the list, passing the element's value as the function argument. The function must return a value. The result of minVal in this case is the element that minimizes func(). Note that the element value is returned, not the return value of func.
For example, if lst is a list of string values, lst.minVal({x: x.length()}) returns the shortest string in the list.
overlapsWith(lst) [a3L]
true
or nil
accordingly.
prepend(val)
removeElementAt(index)
If index is negative, it counts from the end of the list: -1 is the last element, -2 is the second to last, and so on. Otherwise, index 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)
If either index is negative, it counts from the end of the list: -1 is the last element, -2 is the second to last, and so on. Otherwise, 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.
shuffle() [a3L]
sort(descending?, comparisonFunction?)
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 second, 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 });
splice(startIndex, deleteCount, ...)
If startIndex is negative, it counts from the end of the list: -1 is the last element, -2 is the second to last, and so on. Use 0 to indicate one past the last element, to insert the new elements after the last existing element.
You can get the same effect as this method using a combination of removeRange() and insertAt(). splice() is clearer and more concise for cases where you want to replace a range with new values. It's also a little more efficient, since it doesn't have to construct an extra list to hold the intermediate result between the deletion and insertion.
strComp(lst, cmp) [a3L]
true
if all the corresponding strings in the two lists are the same
(according to cmp) and nil
otherwise.
sublist(start, length?)
Examples:
[1, 2, 3].sublist(2) yields [2, 3] [1, 2, 3].sublist(2, 1) yields [2] [1, 2, 3, 4, 5].sublist(1, -2) yields [1, 2, 3] [1, 2, 3, 4, 5].sublist(2, -2) yields [2, 3]
subset(func)
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});
toList() [a3L]
toList()
on a List simply returns the same List.
valWhich(cond)