Files
modeling-app/docs/kcl-std/functions/std-array-reduce.md
Nick Cameron b19acd550d Type check and coerce arguments to user functions and return values from std Rust functions (#6958)
* Shuffle around function call code

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Refactor function calls to share more code

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Hack to leave the result of revolve as a singleton rather than array

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-05-19 16:50:15 +12:00

92 KiB

title, subtitle, excerpt, layout
title subtitle excerpt layout
reduce Function in std::array manual
reduce(
  @array: [any],
  initial: any,
  f: fn(any, accum: any): any,
): any

Take a starting value. Then, for each element of an array, calculate the next value, using the previous value and the element.

Arguments

Name Type Description Required
array [any] Each element of this array gets run through the function f, combined with the previous output from f, and then used for the next run. Yes
initial any The first time f is run, it will be called with the first item of array and this initial starting value. Yes
f fn(any, accum: any): any Run once per item in the input array. This function takes an item from the array, and the previous output from f (or initial on the very first run). The final time f is run, its output is returned as the final output from reduce. Yes

Returns

any

Examples

// This function adds two numbers.
fn add(@a, accum) { return a + accum }

// This function adds an array of numbers.
// It uses the `reduce` function, to call the `add` function on every
// element of the `arr` parameter. The starting value is 0.
fn sum(@arr) { return reduce(arr, initial = 0, f = add) }

/*
The above is basically like this pseudo-code:
fn sum(arr):
    sumSoFar = 0
    for i in arr:
        sumSoFar = add(i, sumSoFar)
    return sumSoFar
*/

// We use `assert` to check that our `sum` function gives the
// expected result. It's good to check your work!
assert(sum([1, 2, 3]), isEqualTo = 6, tolerance = 0.1, error = "1 + 2 + 3 summed is 6")

Rendered example of reduce 0

// This example works just like the previous example above, but it uses
// an anonymous `add` function as its parameter, instead of declaring a
// named function outside.
arr = [1, 2, 3]
sum = reduce(arr, initial = 0, f = fn (@i, accum) { return i + accum })

// We use `assert` to check that our `sum` function gives the
// expected result. It's good to check your work!
assert(sum, isEqualTo = 6, tolerance = 0.1, error = "1 + 2 + 3 summed is 6")

Rendered example of reduce 1

// Declare a function that sketches a decagon.
fn decagon(@radius) {
  // Each side of the decagon is turned this many radians from the previous angle.
  stepAngle = ((1/10) * TAU): number(rad)

  // Start the decagon sketch at this point.
  startOfDecagonSketch = startSketchOn(XY)
    |> startProfile(at = [(cos(0)*radius), (sin(0) * radius)])

  // Use a `reduce` to draw the remaining decagon sides.
  // For each number in the array 1..10, run the given function,
  // which takes a partially-sketched decagon and adds one more edge to it.
  fullDecagon = reduce([1..10], initial = startOfDecagonSketch, f = fn(@i, accum) {
      // Draw one edge of the decagon.
      x = cos(stepAngle * i) * radius
      y = sin(stepAngle * i) * radius
      return line(accum, end = [x, y])
  })

  return fullDecagon

}

/*
The `decagon` above is basically like this pseudo-code:
fn decagon(radius):
    stepAngle = ((1/10) * TAU): number(rad)
    plane = startSketchOn(XY)
    startOfDecagonSketch = startProfile(plane, at = [(cos(0)*radius), (sin(0) * radius)])

    // Here's the reduce part.
    partialDecagon = startOfDecagonSketch
    for i in [1..10]:
        x = cos(stepAngle * i) * radius
        y = sin(stepAngle * i) * radius
        partialDecagon = line(partialDecagon, end = [x, y])
    fullDecagon = partialDecagon // it's now full
    return fullDecagon
*/

// Use the `decagon` function declared above, to sketch a decagon with radius 5.
decagon(5.0) |> close()

Rendered example of reduce 2