A semi-colon delimited list of string values. In terms of stored data Sets and Lists are the same: a string containing one or more semi-colon delimited items. The difference is in the way Tinderbox handles the two data types, as lists may contain duplicate items. Although the Set-type pre-dates List-type in Tinderbox, Lists should be thought of as the underlying form and Sets as a refined (de-duplicated) form of List.
Lists, unlike Sets, allow duplicate values. To de-dupe a List, use the .unique dot-operator:
An older alternate method, which may be found in old demos is simply put its contents into a Set-type attribute:
If $MySet and $MyList both have the value "cats;dogs": the following have different outcomes:
$MySet=$MySet + "dogs" gives "cats;dogs"
$MyList=$MyList + "dogs" gives "cats;dogs;dogs"
The Set attribute does not add the duplicate value but the List does; List data values are stored in the order added. Be careful using this method to add a list value as if run in a rule, the terms will be re-added as a new value each time the rule runs!
Also beware an assumed pre-assignment concatenation:
$MyList=$MyList + "gun" + " " + "dogs" gives "cats;gun;dogs" not "cats;gun dogs"
$MyList=$MyList +( "gun" + " " + "dogs") gives "cats;gun dogs"
If setting a List's literal values via action code note the string must be quoted:
Adding and deleting values
With a List you can add/remove individual or multiple values and test its contents. In actions, + adds an item to a set if it is not already present, and - removes it if it is present. Values must be enclosed in double quotes. If $PetTypes' value is "cats;dogs", then:
$PetTypes=$PetTypes+"rabbits" adds the new value
$PetTypes=$PetTypes+"rabbits" unlike a Set, this adds a second instance of "dogs" to the end of the list.
$PetTypes=$PetTypes-"dogs" leaves only "cats" as a value.
Testing (querying) Sets & Lists
To test a set or list, use the .contains() operator, syntax
true if any Set/List discrete value exactly matches the designated tested_value; if case sensitivity is irrelevant for the query use .icontains(). If a user attribute
$PetTypes has a value of "dogs;cats" then
$PetTypes.contains("dogs") is true,
$PetTypes.contains("dog") is false
This is because Let/List matching does not allow partial (regex) matches unlike with String-type data.
$PetTypes.contains("Dogs").lowercase is true
$PetTypes.icontains("DOGS") is true
It can be useful to use a stored value as the search pattern, for instance using the name of an agent as the search term:
$PetTypes.contains($MyString) is true
Escaping literal semi-colons
If a list item must contain a semi-colon, it must be escaped, using a backslash, '\;'. Once the backslash is entered, it disappears and the list item containing the semi-colon is enclosed in double-quotes. Do not try to escape a value by adding the quotes directly, use the backslash method. Action code methods to make lists will treat a '\;' in an input string as an escape and act accordingly. Consider using String.replace() as a method for escaping backslashes (though only where intended!).
Listing and Exporting sets
System Attributes: Sets vs. Lists
Most group-scope operators can work with lists or sets, as well as the find() operator (whose own output is a list) and literal list-based group designators; exceptions include $KeyAttributes where duplicates would not be helpful. It is the declared data type of the attribute being collected that informs the operator to return a list or set.