Collections
As any modern language, WarpScript implements a few collections types. In this tutorial, you will learn how to manage lists, maps, and sets.
Lists
Under the hood, this is a java ArrayList. This kind of resizable list allow any kind of elements, including NULL
. Order is always preserved. REVERSE
reverse the order of the collection.
To build a LIST, you can use []
to put an empty list on the stack, or you can put a MARK
on the stack with [
, put on the stack the elements of the list, then call the ]
function. The ]
function will take every element on the stack, put them in a list, and stops when it finds a MARK.
This is a mutable object. It means adding or removing an element do not return a copy of the list.
In the upper example, you can see $mylist is modified by the +!
operation. This is why you can often DROP
the result of +!
.
APPEND
has the same behavior as +!
, except it takes a list as input.
Lists are mutable. Saving a list variable in a new variable do not copy the list. If you do so, you will just have two variable pointing to the same object.
If you want to make a copy of the list, you need to CLONE
it.
CLONEREVERSE
clones and reverse the list order in the same operation.
LSORT
allow you to sort lists of homogeneous elements.
A LIST can contain heterogeneous objects. Of course, you cannot compare different objects, so the resulting list won't be sortable.
You can create your own sort criteria and use SORTBY
. In the following example, sorting lists by their length is really easy.
See also GROUPBY
for advanced grouping of lists.
GET
, SET
, REMOVE
allow you to manipulate LIST elements. To check whether an element is present in a list, use CONTAINS
. The first element of a LIST has index zero.
To iterate on list elements, you can use FOREACH
or LMAP
functions. FOREACH
has no output format, you manage the stack the way you want. LMAP
will build an output list with the elements you let on top of the stack.
SUBLIST
allow you to extract a sublist from a LIST.
You can recursively FLATTEN
a list of list of elements. LFLATMAP
could be used for a non recursive flattening of a LIST.
Flattening is limited to 16 levels of sublist. The following example will raise an exception:
ZIP
is a way to merge several lists in a new list of list. The first output list will contain the first elements of each input list, the second output list will contain the second elements of each input list, and so on. If an input list is a singleton, its unique value will be considered for every output list.
Explicit Warning: LIST manipulations are not synchronized. If you plan to parallelize macros that modify the same list, you need to use SYNC
. See CEVAL
for more information.
Maps
Maps are collections of key value pairs. Each key is unique. The simplest example is a dictionary: Every word is unique (the key), and has a definition (which could be the same for two different words). The key and the values could be any kind of objects, even NULL.
Under the hood, this is a java LinkedHashMap. It means the order of elements is guaranteed. Iteration functions will iterate in the order in which the entries were put into the map. In Python, it will be an ordered dictionary.
To build a MAP, you can use {}
to put an empty map on the stack, or you can put a MARK
on the stack with {
, put on the stack the key values pairs of the map, then call the }
function. The }
function will take every pair of elements on the stack, put them in a map, and stops when it finds a MARK.
A MAP is a mutable object. It means adding or removing an element do not return a copy of the list. Storing a map variable into another variable just copy a reference to the same object in memory, except if you CLONE it:
When you build a map from stack elements, you cannot have key duplicates. When you PUT
a new key value pair, or APPEND
a new MAP to an existing one:
- If the key does not exist, the new key value is inserted at the end of the MAP.
- If the key exists in the MAP, its value is updated with the new one
When you retrieve a value from its key with GET
:
- If the key exists, GET returns the value
- If the key does not exist, GET returns NULL.
To make the difference between a NULL value and a non-existing key, you can use CONTAINSKEY
.
It means building counters of occurrence is really easy. In this example, I count the automotive brand occurrence in a list:
If your keys are homogeneous and sortable, you can sort the map up to its keys with MSORT
.
Sets
A SET is a collection of unique elements. Under the hood, this is a java HashSet. It means the iteration order is not guaranteed at all.
The SET type cannot be represented on in the JSON stack output. You will see a "null" output. The only way to visualize it is to turn it into a LIST with SET->
.
Building a set is very similar to maps or lists building. To build a SET, you can use ()
to put an empty set on the stack, or you can put a MARK
on the stack with (
, put on the stack the elements of the set, then call the )
function. The )
function will take every element on the stack, put them in a set, and stops when it finds a MARK.
You can also build it from a list with ->SET
.
Pro Tips
Some WarpScript functions sometimes take arguments in a LIST. For example, when you FETCH data. The result is a list of GTS on top of the stack. You need to BUCKETIZE these data as soon as you get them. You can use SWAP to put a MARK below the top of the stack: