Lists, maps and text
Lists and maps
fn squares(xs: &[i64]) -> List[i64] = xs.map(fn(x: i64) => x * x)
fn evens(xs: &[i64]) -> List[i64] = [x for x in xs if x % 2 == 0]
fn total(xs: &[i64]) -> i64 = xs.fold(0, fn(acc: i64, x: i64) => acc + x)
fn count_words(words: &[text]) -> Map[text, u32]
var m: Map[text, u32] = {}
for w in words
m[w] = (m.get(w) catch 0) + 1
return m
const XS: List[i64] = [1, 2, 3, 4]
const WORDS: List[text] = ["a", "b", "a"]
check squares(&XS) == [1, 4, 9, 16]
check evens(&XS) == [2, 4]
check total(&XS) == 10
check count_words(&WORDS)["a"] == 2
check (count_words(&WORDS).get("z") catch 0) == 0
List[i64]is a list ofi64.[1, 2, 3, 4]is a list literal.&[i64]is a borrowed slice: a view of a list or array that the function reads but does not own.xs.map(fn(x: i64) => x * x)applies a function to every element.fn(x: i64) => ...is a function written inline.[x for x in xs if x % 2 == 0]builds a new list from the old one.foldcombines the elements into one value, starting from0.Map[text, u32]maps text keys tou32values.m.get(w)fails when the key is missing, andcatch 0supplies a default.
Text
fn shout(s: &text) -> text = s.strip().upper() + "!"
fn is_palindrome(s: &text) -> bool
let t = [c for c in s.lower().chars() if c.isalpha()]
return t == t.reverse()
const GREETING: text = " hi "
const PHRASE: text = "Never odd or even"
check shout(&GREETING) == "HI!"
check is_palindrome(&PHRASE)
check "héllo".len() == 6
check "héllo"[1:3] == "é"
Text is stored as UTF-8. len() counts bytes, not characters: "héllo"
has five characters and six bytes, because é takes two bytes.
s[1:3] takes the bytes from position 1 up to 3, which here is exactly
the é. Slicing in the middle of a character traps. To go through text one
character at a time, use chars() or for c in s.
What you learned
List,Map, slices, inline functions and list comprehensions.- Text is UTF-8, measured and indexed in bytes.