This package provides some convinient functional functions for typst to use on arrays.
To use this package simply #import "@preview/funarray:0.3.0"
. To import all functions use : *
and for specific ones, use either the module or as described in the typst docs.
Almost all functions are one-liners, which could, instead of being loaded via a package import, also be just copied directly into your source files.
A prettier und easier to read version of the documentation exists in the example folder, which is done in typst and exported to pdf. Otherwise, bellow is the markdown version.
Let us define
a = (1, "not prime", 2, "prime", 3, "prime", 4, "not prime", 5, "prime")
The chunks function translates the array to an array of array. It groups the elements to chunks of a given size and collects them in an bigger array.
chunks(a, 2) = ( (1, "not prime"), (2, "prime"), (3, "prime"), (4, "not prime"), (5, "prime") )
The unzip function is the inverse of the zip method, it transforms an array of pairs to a pair of vectors. You can also give input an array of n
-tuples resulting in in n
arrays.
unzip(b) = ( (1, 2, 3, 4, 5), ( "not prime", "prime", "prime", "not prime", "prime" ) )
The cycle function concatenates the array to itself until it has a given size.
let c = cycle(range(5), 8)
c = (0, 1, 2, 3, 4, 0, 1, 2)
Note that there is also the functionality to concatenate with +
and *
in typst.
This function provides a running window
windows(c, 5) = ( (0, 1, 2, 3, 4), (1, 2, 3, 4, 0), (2, 3, 4, 0, 1), (3, 4, 0, 1, 2) )
whereas the circular version wraps over.
circular-windows(c, 5) = ( (0, 1, 2, 3, 4), (1, 2, 3, 4, 0), (2, 3, 4, 0, 1), (3, 4, 0, 1, 2), (4, 0, 1, 2, 4), (0, 1, 2, 4, 0), (1, 2, 4, 0, 1), (2, 4, 0, 1, 2) )
The partition function seperates the array in two according to a predicate function. The result is an array with all elements, where the predicate returned true followed by an array with all elements, where the predicate returned false.
let (primesp, nonprimesp) = partition(b, x => x.at(1) == "prime")
primesp = ((2, "prime"), (3, "prime"), (5, "prime"))
nonprimesp = ((1, "not prime"), (4, "not prime"))
There is also a partition-map function, which after partition also applies a second function on both collections.
let (primes, nonprimes) = partition-map(b, x => x.at(1) == "prime", x => x.at(0))
primes = (2, 3, 5)
nonprimes = (1, 4)
This functions groups according to a predicate into maximally sized chunks, where all elements have the same predicate value.
let f = (0,0,1,1,1,0,0,1)
let g = group-by(f, x => x == 0)
g = ((0, 0), (1, 1, 1), (0, 0), (1,))
Typst has a flatten
method for arrays, however that method acts recursively. For instance
(((1,2,3), (2,3)), ((1,2,3), (1,2))).flatten() = (1, 2, 3, 2, 3, 1, 2, 3, 1, 2)
Normally, one would only have flattened one level. To do this, we can use the typst array concatenation method +, or by folding, the sum method for arrays:
(((1,2,3), (2,3)), ((1,2,3), (1,2))).sum() = ((1, 2, 3), (2, 3), (1, 2, 3), (1, 2))
To handle further depth, one can use flatten again, so that in our example:
(((1,2,3), (2,3)), ((1,2,3), (1,2))).sum().sum() = (((1,2,3), (2,3)), ((1,2,3), (1,2))).flatten()
This function has been removed in version 0.3, as typst 0.8 provides such functionality by default.
These functions do exactly as they say.
take-while(h, x => x < 1) = (0, 0, 0.25, 0.5, 0.75)
skip-while(h, x => x < 1) = (1, 1, 1, 0.25, 0.5, 0.75, 0, 0, 0.25, 0.5, 0.75, 1)
The core functions are defined in funarray-unsafe.typ
. However, assertions (error checking) are not there and it is generally not being advised to use these directly. Still, if being cautious, one can use the imported funarray-unsafe
module in funarray(.typ)
. All function names are the same.
To do this from the package, do as follows:
#import @preview/funarray:0.3.0
#funarray.funarray-unsafe.chunks(range(10), 3)