Skip to content

Reduction and Slicing

fold is the universal reducer: it takes an initial accumulator and a closure |acc, x| new_acc, collapsing the entire sequence into a single value. Sum, product, maximum, and concatenation all follow the same pattern:

Sum, factorial, maximum and string join — all expressed with fold.

05-iter-fold-reduce.zolo
Playground
// Feature: `Iter.fold` — reduction with an accumulator

// Syntax: `it.fold(init, |acc, x| new_acc)`.

// When to use: collapse an iterator into a single value (sum, product,

// max, concat, struct build, etc.).


use std::Iter

// Classic sum.

let total = Iter::range(1, 6).fold(0, |acc, x| acc + x)
print("sum = {total}")

// expected: sum = 15


// Product.

let prod = Iter::range(1, 6).fold(1, |acc, x| acc * x)
print("5! = {prod}")

// expected: 5! = 120


// Maximum (init = conceptually the first element; here we use a small

// known value).

let mx = Iter::from([3, 1, 4, 1, 5, 9, 2, 6]).fold(0, |acc, x| {
  if x > acc { return x }
  return acc
})
print("max = {mx}")

// expected: max = 9


// Concatenate strings.

let words = Iter::from(["zolo", "is", "fun"])
let joined = words.fold("", |acc, w| {
  if acc == "" { return w }
  return acc + " " + w
})
print(joined)
// expected: zolo is fun

take(n) keeps only the first n elements; skip(n) discards the first n. Combined, they act as pagination over any iterator, including long or infinite ranges:

take, skip, skip+take window; behavior when the source is smaller than n.

06-iter-take-skip.zolo
Playground
// Feature: `Iter.take` and `Iter.skip`

// Syntax: `it.take(n)` keeps the first n; `it.skip(n)`

// drops the first n.

// When to use: paginate, limit infinite ranges, skip headers.


use std::Iter

// take — grabs the first 5.

let first5 = Iter::range(0, 100).take(5)
print(first5.collect())

// expected: [0, 1, 2, 3, 4]


// skip — drops the first 3.

let after3 = Iter::range(0, 8).skip(3)
print(after3.collect())

// expected: [3, 4, 5, 6, 7]


// take + skip = window [3, 6) over 0..100.

let window = Iter::range(0, 100).skip(3).take(3)
print(window.collect())

// expected: [3, 4, 5]


// take on a finite source: truncates when it runs out before n.

let small = Iter::range(0, 3).take(10)
print(small.collect())

// expected: [0, 1, 2]


// skip beyond size — returns empty.

let nothing = Iter::range(0, 3).skip(10)
print(nothing.collect())
// expected: []

Challenge

Use Iter::range(0, 100).skip(10).take(5) to obtain the "second page" of size 5 from a list of 0 to 99. Verify the expected result.

enespt-br