Skip to content

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.

01-push-pop.zolo
Playground
// 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.

02-map.zolo
Playground
// 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.

03-filter.zolo
Playground
// 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.

04-reduce.zolo
Playground
// 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.

05-find-and-contains.zolo
Playground
// 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.

06-flat-and-each.zolo
Playground
// 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.

enespt-br