kcl-stdfunctionsreduce

reduceFunction in std::array

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

reduce(
  @array: [any],
  initial: any,
  f: fn(any, accum: any): any,
): any

Arguments

NameTypeDescriptionRequired
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
initialanyThe first time f is run, it will be called with the first item of array and this initial starting value.Yes
ffn(any, accum: any): anyRun 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 - The any type is the type of all possible values in KCL. I.e., if a function accepts an argument with type any, then it can accept any value.

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

Found a typo?