Arrays (std::array)
Arrays in Zolo are variable-length sequences. Declare with let mut
to get a mutable array. Methods are available as method form
(arr.map(...)) and module form (Array::map(arr, ...)). Import with
use std::Array when using the module form.
Push and pop
push appends to the end; pop removes and returns the last element — the
classic LIFO stack pattern.
Incremental construction and LIFO stack with push/pop.
// Feature: Array push / pop — mutation at the end of the array
// When to use: building arrays incrementally, using as a stack.
use std::Array
// `let mut` allows mutating the array.
let mut nums = [1, 2, 3]
// Push appends at the end.
nums.push(4)
nums.push(5)
print(nums)
// expected: [1, 2, 3, 4, 5]
print(nums.len()) // expected: 5
// Pop removes and returns the last element.
let last = nums.pop()
print(last) // expected: 5
print(nums) // expected: [1, 2, 3, 4]
// Classic LIFO stack.
let mut stack = []
stack.push("a")
stack.push("b")
stack.push("c")
print(stack.pop()) // expected: c
print(stack.pop()) // expected: b
print(stack.len()) // expected: 1
// Equivalent module form.
let mut xs = [10]
xs.push(20)
xs.push(30)
print(xs)
// expected: [10, 20, 30]
Transformation with map
map applies a function to every element and returns a new array of the same
length. The original array is not modified.
Double, square, type-convert, transform strings — map is always non-destructive.
// Feature: Array.map — transforms each element while preserving length
// When to use: applying the same transformation to a whole collection.
use std::Array
let nums = [1, 2, 3, 4, 5]
// Double each number.
let doubled = nums.map(|x| x * 2)
print(doubled)
// expected: [2, 4, 6, 8, 10]
// Square.
let squares = nums.map(|x| x * x)
print(squares)
// expected: [1, 4, 9, 16, 25]
// Type conversion: int -> str.
let labels = Array::map([1, 2, 3], |n| "item-{n}")
print(labels[0]) // expected: item-1
print(labels[2]) // expected: item-3
// Map over strings.
let names = ["alice", "bob", "carol"]
let upper = names.map(|s| s.upper())
print(upper)
// expected: [ALICE, BOB, CAROL]
// Original untouched.
print(nums)
// expected: [1, 2, 3, 4, 5]
Filtering with filter
filter keeps only the elements that satisfy the predicate.
Even numbers, greater than 5, non-empty strings; filter + map composition.
// Feature: Array.filter — keeps only elements that satisfy a predicate
// When to use: selecting a subset, removing invalid items.
use std::Array
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// Even numbers.
let evens = nums.filter(|x| x % 2 == 0)
print(evens)
// expected: [2, 4, 6, 8, 10]
// Greater than 5.
let big = nums.filter(|x| x > 5)
print(big)
// expected: [6, 7, 8, 9, 10]
// Filter non-empty strings.
let words = ["foo", "", "bar", "", "baz"]
let nonempty = words.filter(|s| s.len() > 0)
print(nonempty)
// expected: [foo, bar, baz]
// Compose with map — double only the evens.
let just_evens = nums.filter(|x| x % 2 == 0)
let evens_doubled = just_evens.map(|x| x * 2)
print(evens_doubled)
// expected: [4, 8, 12, 16, 20]
Aggregation with reduce
reduce(fn, init) accumulates elements into a single value. The second argument
is the initial accumulator value.
Sum, product, manual maximum and string concatenation via reduce.
// Feature: Array.reduce — aggregates elements into a single value
// When to use: summing, counting, finding max, building a final string.
use std::Array
let nums = [1, 2, 3, 4, 5]
// Sum — accumulator starts at 0.
let sum = nums.reduce(|acc, x| acc + x, 0)
print(sum) // expected: 15
// Product — accumulator starts at 1.
let prod = nums.reduce(|acc, x| acc * x, 1)
print(prod) // expected: 120
// Manual maximum.
let max = nums.reduce(|acc, x| if x > acc { x } else { acc }, 0)
print(max) // expected: 5
// Concatenate strings.
let words = ["hello", " ", "zolo", "!"]
let joined = words.reduce(|acc, w| acc + w, "")
print(joined)
// expected: hello zolo!
// Count even numbers in the list.
let inputs = [1, 2, 3, 4, 5, 6]
let evens_count = inputs.reduce(|acc, x| if x % 2 == 0 { acc + 1 } else { acc }, 0)
print(evens_count) // expected: 3
Search with find and contains
contains tests membership by value; find returns the first element that
satisfies the predicate, or nil if none matches.
Plain contains; find with a predicate; if candidate != nil pattern.
// Feature: Array.find / Array.contains — searching in arrays
// When to use: getting the first item matching a criterion, testing membership.
use std::Array
let nums = [1, 2, 3, 4, 5]
// contains — simple membership by value.
print(nums.contains(3)) // expected: true
print(nums.contains(99)) // expected: false
// find — first element satisfying the predicate, or nil.
let first_even = nums.find(|x| x % 2 == 0)
print(first_even) // expected: 2
let big = nums.find(|x| x > 100)
print(big) // expected: nil
// find on a string array.
let names = ["alice", "bob", "carol", "dave"]
let starts_c = names.find(|n| n.starts_with("c"))
print(starts_c) // expected: carol
// Combine with if-let for safe usage.
let candidate = nums.find(|x| x > 3)
if candidate != nil {
print("found: {candidate}")
} else {
print("nothing")
}
// expected: found: 4
Flattening and side-effect iteration
flat() flattens one level of nesting. each runs a block per element
and returns nil — suitable for side effects such as print.
flat to join sub-arrays; each for printing; map + flat composition as flatMap.
// Feature: Array.flat / Array.each — flattening and iteration with side effects
// When to use: combining nested arrays, performing an action per item without a return.
use std::Array
// flat — flattens one level of nesting.
let nested = [[1, 2], [3, 4], [5]]
let flat = nested.flat()
print(flat)
// expected: [1, 2, 3, 4, 5]
// flat with arrays of varying sizes — all become items.
let mixed = [[1], [], [2, 3, 4], [5]]
print(mixed.flat())
// expected: [1, 2, 3, 4, 5]
// each — side effect per item, returns nil.
print("--- each ---")
Array::each([10, 20, 30], |x| print("item: {x}"))
// expected: --- each ---
// expected: item: 10
// expected: item: 20
// expected: item: 30
// Classic combination: flat + map for "flatMap".
let phrases = ["zolo lang", "rust roxo"]
let tokens = phrases.map(|s| s.split(" ")).flat()
print(tokens)
// expected: [zolo, lang, rust, roxo]
Challenge
Given an array of words, use filter + map to obtain only words
longer than 3 letters, in upper case. Then sum the lengths with reduce.
See also