Add reduce method to array (#3911)

This commit is contained in:
JustForFun88 2024-04-30 17:21:40 +05:00 committed by GitHub
parent 97de0a0595
commit d7838ab128
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 0 deletions

View File

@ -882,6 +882,36 @@ impl Array {
})
.collect()
}
/// Reduces the elements to a single one, by repeatedly applying a reducing
/// operation.
///
/// If the array is empty, returns `none`, otherwise, returns the
/// result of the reduction.
///
/// The reducing function is a closure with two arguments: an 'accumulator', and an element.
///
/// For arrays with at least one element, this is the same as `array.fold`
/// with the first element of the array as the initial accumulator value, folding
/// every subsequent element into it.
#[func]
pub fn reduce(
self,
/// The engine.
engine: &mut Engine,
/// The callsite context.
context: Tracked<Context>,
/// The reducing function. Must have two parameters: One for the
/// accumulated value and one for an item.
reducer: Func,
) -> SourceResult<Value> {
let mut iter = self.into_iter();
let mut acc = iter.next().unwrap_or_default();
for item in iter {
acc = reducer.call(engine, context, [acc, item])?;
}
Ok(acc)
}
}
/// A value that can be cast to bytes.

View File

@ -492,3 +492,16 @@
--- array-unclosed ---
// Error: 3-4 unclosed delimiter
#{(}
--- array-reduce ---
// Test the `reduce` method.
#test(().reduce(grid), none)
#test((1, 2, 3, 4).reduce((s, x) => s + x), 10)
--- array-reduce-missing-reducer ---
// Error: 2-13 missing argument: reducer
#().reduce()
--- array-reduce-unexpected-argument ---
// Error: 19-21 unexpected argument
#(1, 2, 3).reduce(() => none)