Frag Logo
  Frag Home | Frag SF Project   index | contents | previous | next

Lists

Lists as Data Structures

A second fundamental data structures in Frag, besides objects and strings, are lists. A list contains a number of elements separated by whitespaces. For instance a method definition:
A method myMethod {a b c} {
    puts "$a $b $c"
}
is a list of 5 elements: object name, the method operation name, method name, argument list, and body. Actually, each invocation in Frag is a list.

The elements of a list can either be strings (or what they are converted to internally, like object names or integers), or other lists. For instance, the argument list a b c in the method definition above is an embedded list. Lists can be delimited using curly braces {...}.

Expand Syntax

Sometimes lists that are stored in variables or returned by commands are in an unhandy format, because they are not expanded, but an expanded list is needed. Consider the following example:
Command create sum -cmd {args} {
    set result 0
    foreach n $args {
        set result ($result + $n)
    }
    return $result
}
This method calculates the sum of an arbitrary number of arguments in a list. But this only works with an expanded list, such as the following:
sum 1 2 3
The following would not work:
set a {1 2 3}
sum $a
This would yield the error "value '1 2 3' is not a number" because a list with only one element {1 2 3} is given as a argument and Frag does not know how to convert {1 2 3} into a number that can be used in the addition. We can avoid this by using the expand syntax, which uses * after $ or opening square brackets: $* or [* ...] to expand the list.

Hence the following variable expansion works:
set a {1 2 3}
sum $*a
Similarly, invocation expansion works as well:
set a {1 2 3}
sum [* get a]
The expand syntax can be used on any variable read using $ or any invocation in square brackets.

List Manipulation

The command list offers a number of methods for manipulating lists. All list methods have no side effect on the lists used as input - they only manipulate the result list. In addition, there is the command append (explained first) which modifies a list in a variable. This command is more efficient than copying lists to and from variables; hence, it should be used for the common use case of incrementally building up a list variable (e.g., using a for or foreach loop).

append

Syntax

append <variableName> ?new elements ...?

Description

append appends an arbitrary number of new elements to a given list stored in variableName.

Example

The following code returns the list a b c 0 2:
set a {a b c}
append a 0 2
get a

list build

Syntax

list build ? list elements ...?

Description

list build explicitly tells the interpreter to build a list from an arbitrary number of arguments. Without argument, list build returns an empty list.

Example

The following simple example builds a list of two elements: {a b} and c, the first being itself a list of two elements (a and b).
list build {a b} c

list delete

Syntax

list delete <list> <element>
Options: -first, -all

Description

list delete deletes the list element element from list. Per default only the first element is deleted (this can also be specified using -first). Optionally, -all specifies that all occurrences of element are deleted from list.

Example

The following code deletes the first element e from the list. The result is the list a b cd e.
list delete {a b cd e e} e
The following code deletes all elements e from the list. The result is the list a b cd.
list delete -all {a b cd e e} e

list index

Syntax

list index <list> <index>

Description

list index returns the index-th element in the list. Counting starts with 0.

Example

The following code returns a b because this is the element of the list at index 0.
list index {{a b} c d e} 0
The following code returns d because this is the element of the list at index 2.
list index {{a b} c d e} 2

list insert

Syntax

list insert <list> <index> <insert list>

Description

list insert inserts the elements of the list insert list at index into the list and returns the modified list.

Example

The following code returns a b b2 b3 c:
list insert {a b c} 2 {b2 b3}

list join

Syntax

list join <list> ?join string?

Description

list join returns a string formed by joining all of the elements of list together using join string for separating each adjacent pair of elements. The join string argument defaults to a space character.

Example

The following code returns the string: a, b, c
list join {a b c} ", "

list length

Syntax

list length <list>

Description

list length returns the number of list elements in list.

Example

The following code returns 2, because the list built by list build has two elements: {a b} and c.
list length [list build {a b} c]

list replace

Syntax

list replace <list> <index1> <index2> <new list>

Description

list replace replaces the content of list from index1 to index2 with the content of the new list argument. If the new list is empty the elements in the lists get deleted.

Example

The following code replaces the elements from index 2 to 4 of the given list with the list 5 6 7. The result is: a b 5 6 7 f.
list replace {a b c d e f} 2 4 {5 6 7}
The following code deletes the elements from index 1 to 3 of the given list (i.e., replaces them with an empty list). The result is the list a e.
list replace {a b cd e e} 1 3 {}

list search

Syntax

list search ?-options ...? <list> <match string>
Options: -exact, -pattern, -first, -all, -indices, or -elements

Description

list search searches through a list for a given match string. There are a number of options for a search which can be combined. A search can either be an exact search (specified by -exact) or a search using pattern matching (specified by -pattern). For details on pattern matching see Section Pattern Matching. -pattern is the default. The search can either return only the first match (specified by -first) or all matching results (specified by -all). -first is the default. Finally, a search can return the indices that match (specified by -indices) or the list of elements that match (specified by -elements). -indices is the default.

Example

Without options, the default options are assumed. Hence the following search returns the index of the first exact match: 1.
list search {1 2 3 4 12 22 23} 2
We can use the -all option to find all indices of all matches:
list search -all {1 2 3 4 12 22 23} 2
The above example still returns only 1 because that's the only exact match, but if we additionally activate pattern matching, 1 5 6 is found:
list search -all -pattern {1 2 3 4 12 22 23} 2*
If we want the elements that match rather than the indices, we need to use the elements option, and get the result 2 22 23:
list search -all -pattern -elements {1 2 3 4 12 22 23} 2*

list sort

Syntax

list sort ?-options ...? <list>
Options: -ascii, -object, -decreasing, -dictionary, -increasing, -integer, or -double

Description

list sort
sorts the list following the sort criteria given as (optional) options and returns the sorted list.

The sort mode defines how values are compared. The default is -ascii, which performs a lexical comparison of the ascii values of each letter of the list elements (i.e., they are treated as strings).

The -dictionary option also performs a lexical comparison, but following dictionary rules instead of a lexical comparison character by character. For instance, in -ascii mode Item 11 comes after Item 100, because the character 0 has a lower ascii value than 1, but in -dictionary mode, Item 11 comes before Item 100.

The -integer option tries to convert all list elements to integers and sorts the list using an integer value comparison. The -double option tries to convert all list elements to doubles and sorts the list using double value comparison. In both cases, if a list element cannot be converted, an error is thrown.

The -object option takes an object ID as argument. This object is used for comparison. The object must be a Command (see User-defined Commands), which takes two values to compare as arguments, such as:
Command create compareCmd -cmd {a b} {...}
The Command works equally to the string compare (see string compare) method. That is, the result is "-1" if argument a precedes argument b. The result is a "1" if argument a follows argument b. The result is zero if a and b are equal.

The option -decreasing sorts the list in decreasing fashion (according to the other search criteria), and -increasing returns the increasingly sorted list. -increasing is the default.

Example

The following simple example returns the list 1 a ab abdeq ac, which is the list sorted by a standard increasing lexical comparison.
list sort {abdeq ab 1 ac a}
Here the default -increasing is chosen. The same search with -decreasing returns the list ac abdeq ab a 1:
list sort -decreasing {abdeq ab 1 ac a}
To sort an integer list, we can issue the following invocation. It returns: -42 1 33 40 62 180 180:
list sort -integer {1 180 62 040 180 -42 33}
This can also be combined with -decreasing, which then returns: 180 180 62 40 33 1 -42.
list sort -int -decreasing {1 180 62 040 180 -42 33}
The following code demonstrates the -dictionary option:
set l {a1 a11 a100 a101 a10 a12 a15}
set r1 [list sort $l]
set r2 [list sort -ascii $l]
set r3 [list sort -dictionary $l]
puts "list build $r1 $r2 $r3"
This code prints:
{a1 a10 a100 a101 a11 a12 a15} {a1 a10 a100 a101 a11 a12 a15} {a1 a10 a11 a12 a15 a100 a101}
The first two lists are sorted in -ascii mode. Hence, a100 a101 precede a11 a12 a15. This is not the case in -dictionary mode: Here the standard dictionary sorting rules are applied.

The following creates a sorter command and uses this custom sorter to sort a list by the first list elements of its sub-lists.
Command create sorter -cmd {a b} {
    string compare [list index $a 0] [list index $b 0]
}
list sort -object sorter -dec {{1 a b c} {2 b c} {5 d e} 4}
Of course, Command objects can also be inlined as unnamed objects. The example above could hence be modified to the following shorter form:
list sort -object [Command create -cmd {a b} {
    string compare [list index $a 0] [list index $b 0]
}] -dec {{1 a b c} {2 b c} {5 d e} 4}            

list split

Syntax

list split <string> ?split string?

Description

list split returns a list that is formed by splitting the given string at each position where split string occurs in the string. The split string argument defaults to a space character.

Example

The following code returns the list: {a b c}
list split {a, b, c} ", "

list subList

Syntax

list subList <list> <index1> <index2>

Description

list subList returns a list which is the sub-list (i.e. a specific subList) from index1 to index2 of a given list.

Example

The following code returns the list b cd e:
list subList {a b cd e e} 1 3
The list subList command in the following code returns the sub-list of l ranging from the second element to the last element:
set l {a b c}
list subList $l 1 ([list length $l] - 1)

  index | contents | previous | next