array.fold()
This method operates on an array. You typically fetch documents from a collection as a set, not an Array. For the equivalent Set method, see set instance methods. For differences between Sets and Arrays, see Sets vs. Arrays. |
Description
Iterates through each element in an Array to perform a rolling operation.
For example, you can use fold()
to calculate a rolling sum, concatenate
elements, or perform complex transformations.
fold()
calls a reducer callback function on every element of the Array from
left to right. The reducer function takes two arguments:
-
The accumulator that holds the running result from previous iterations. For the first iteration, a seed value serves as the initial accumulator.
-
The current element’s value from the Array.
The method returns the result of the last iteration. The calling Array isn’t changed.
Fold family methods
FQL supports several methods for folds, which iteratively reduce an Array to a single value. These methods include:
The methods are similar but have the following differences:
-
array.fold()
andarray.foldRight()
accept an initial seed value and use it as the initial accumulator.array.reduce()
andarray.reduceRight()
use the array’s first element as the initial accumulator. -
array.fold()
andarray.reduce()
iterate through the Array’s elements from left to right.array.foldRight()
andarray.reduceRight()
iterate through the Array’s elements from right to left.
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
seed |
Yes |
Initial accumulator value provided to the reducer function. |
|
reducer |
Yes |
Anonymous FQL function to call on each element of the Array. |
Return value
Type | Description |
---|---|
Result of the last reducer function call. For an empty Array, the seed is returned. |
Examples
let iter = [1, 2, 3]
iter.fold(100, (value, elem) => value + elem)
106
Group by operation
FQL doesn’t provide a built-in GROUP BY
operation. However, you use fold()
in an
anonymous FQL function or a
user-defined function (UDF) to
achieve the same result.
As an FQL function:
// Defines an anonymous `groupBy()` function.
// `groupBy()` two arguments:
// * `set`: Set or Array containing data to group
// * `key_fn`: Grouping key for each element
let groupBy = (set, key_fn) => {
// Calls the `fold()` function on the `set`
// Set or Array.
let data: Any = set
data.fold(
// Start with an empty object.
{},
(acc, val) => {
// For each value, get a key using the `key_fn` arg.
let key = key_fn(val)
let existing_group = acc[key] ?? []
// Append the current value to the Set or
// Array for that key.
let new_group = existing_group.append(val)
let new_entry = Object.fromEntries([
[key, new_group]
])
// Return an object with grouped results.
Object.assign(acc, new_entry)
}
)
}
// Call the `groupBy()` function.
// Groups `Product` documents by category name.
groupBy(Product.all(), .category!.name)
You can also define a groupBy()
UDF. This lets you reuse
the function across multiple queries.
You create and manage a UDF as an FSL function schema:
// Defines the `groupBy()` UDF.
// `groupBy()` two arguments:
// * `set`: Set or Array containing data to group
// * `key_fn`: Grouping key for each element
function groupBy (set, key_fn) {
// Calls the `fold()` function on the `set`
// Set or Array.
let data: Any = set
data.fold(
// Start with an empty object.
{},
(acc, val) => {
// For each value, get a key using the `key_fn` arg.
let key: String = key_fn(val)
let existing_group = acc[key] ?? []
// Append the current value to the Set or
// Array for that key.
let new_group = existing_group.append(val)
let new_entry = Object.fromEntries([
[key, new_group]
])
// Return an object with grouped results.
Object.assign(acc, new_entry)
}
)
}
You can create and manage schema using any of the following:
For additional examples using the groupBy()
UDF, see Group By: Aggregate data in Fauna.
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!