Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Collection Functions

WCL’s collection functions work with lists and maps. They are pure — none mutate their input; all return new values.

Reference

FunctionSignatureDescription
lenlen(coll: list|map|string) -> intNumber of elements (or characters for strings)
keyskeys(m: map) -> listOrdered list of a map’s keys
valuesvalues(m: map) -> listOrdered list of a map’s values
flattenflatten(list: list) -> listRecursively flatten nested lists one level
concatconcat(a: list, b: list) -> listConcatenate two lists
distinctdistinct(list: list) -> listRemove duplicate values, preserving first occurrence order
sortsort(list: list) -> listSort in ascending order (strings lexicographic, numbers numeric)
reversereverse(list: list) -> listReverse the order of a list
containscontains(list: list, value) -> boolTrue if value is in the list
index_ofindex_of(list: list, value) -> intZero-based index of first occurrence, or -1 if not found
rangerange(start: int, end: int) -> listList of integers from start (inclusive) to end (exclusive)
zipzip(a: list, b: list) -> listList of [a_i, b_i] pairs; length is the shorter of the two

Examples

len

let n1 = len([1, 2, 3])             // 3
let n2 = len({a: 1, b: 2})          // 2
let n3 = len("hello")               // 5

keys / values

let config = {host: "localhost", port: 5432, db: "main"}
let k = keys(config)    // ["host", "port", "db"]
let v = values(config)  // ["localhost", 5432, "main"]

flatten

let nested = [[1, 2], [3, [4, 5]], [6]]
let flat = flatten(nested)   // [1, 2, 3, [4, 5], 6]

flatten goes one level deep. Call it again for deeper nesting.

concat

let a = [1, 2, 3]
let b = [4, 5, 6]
let c = concat(a, b)    // [1, 2, 3, 4, 5, 6]

distinct

let dupes = ["a", "b", "a", "c", "b"]
let uniq = distinct(dupes)    // ["a", "b", "c"]

sort

let nums = sort([3, 1, 4, 1, 5, 9, 2])
// [1, 1, 2, 3, 4, 5, 9]

let words = sort(["banana", "apple", "cherry"])
// ["apple", "banana", "cherry"]

reverse

let rev = reverse([1, 2, 3, 4])    // [4, 3, 2, 1]

contains

let present = contains([10, 20, 30], 20)    // true
let absent  = contains(["a", "b"], "c")    // false

index_of

let i = index_of(["x", "y", "z"], "y")    // 1
let j = index_of(["x", "y", "z"], "w")    // -1

range

let r = range(0, 5)     // [0, 1, 2, 3, 4]
let r2 = range(3, 7)    // [3, 4, 5, 6]

range is most often used as the source of a for loop:

for i in range(0, 3) {
  item item-${i} { position: i }
}

zip

let names = ["web", "api", "worker"]
let ports = [80, 8080, 9000]
let pairs = zip(names, ports)
// [["web", 80], ["api", 8080], ["worker", 9000]]

If the lists have different lengths, the result has the length of the shorter list.

Combining Collection Functions

Collection functions compose naturally:

let items = [3, 1, 4, 1, 5, 9, 2, 6, 5]
let result = reverse(sort(distinct(items)))
// [9, 6, 5, 4, 3, 2, 1]

For transforming or filtering list elements, see Higher-Order Functions. For numeric aggregation over lists, see Aggregate Functions.