kcl library referencestdarrayreduce

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: FunctionSource,
): 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
fFunctionSourceRun 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 - Any KCL 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