From efad1e71fa699e0d2413d3a6a3ce5a4163e38112 Mon Sep 17 00:00:00 2001 From: SekoiaTree <51149447+SekoiaTree@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:18:27 +0200 Subject: [PATCH] Add sum and product to arrays (#966) --- docs/src/reference/types.md | 14 ++++++++++++++ src/eval/array.rs | 35 +++++++++++++++++++++++++++++++++++ src/eval/methods.rs | 2 ++ tests/ref/compiler/array.png | Bin 9459 -> 8385 bytes tests/typ/compiler/array.typ | 21 +++++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/docs/src/reference/types.md b/docs/src/reference/types.md index f5f7e6e44..24756422b 100644 --- a/docs/src/reference/types.md +++ b/docs/src/reference/types.md @@ -630,6 +630,20 @@ Folds all items into a single value using an accumulator function. and one for an item. - returns: any +### sum() +Sums all items (works for any types that can be added). + +- default: any (named) + If set and the array is empty, sum will return this. +- returns: any + +### product() +Calculates the product all items (works for any types that can be multiplied) + +- default: any (named) + If set and the array is empty, sum will return this. +- returns: any + ### any() Whether the given function returns `{true}` for any item in the array. diff --git a/src/eval/array.rs b/src/eval/array.rs index b04fdab8c..1166ce949 100644 --- a/src/eval/array.rs +++ b/src/eval/array.rs @@ -24,6 +24,7 @@ macro_rules! __array { #[doc(inline)] pub use crate::__array as array; +use crate::eval::ops::{add, mul}; #[doc(hidden)] pub use ecow::eco_vec; @@ -199,6 +200,40 @@ impl Array { Ok(acc) } + /// Calculates the sum of the array's items + pub fn sum(&self, default: Option, span: Span) -> SourceResult { + let mut acc = self + .first() + .map(|x| x.clone()) + .or_else(|_| { + default.ok_or_else(|| { + eco_format!("cannot calculate sum of empty array with no default") + }) + }) + .at(span)?; + for i in self.iter().skip(1) { + acc = add(acc, i.clone()).at(span)?; + } + Ok(acc) + } + + /// Calculates the product of the array's items + pub fn product(&self, default: Option, span: Span) -> SourceResult { + let mut acc = self + .first() + .map(|x| x.clone()) + .or_else(|_| { + default.ok_or_else(|| { + eco_format!("cannot calculate product of empty array with no default") + }) + }) + .at(span)?; + for i in self.iter().skip(1) { + acc = mul(acc, i.clone()).at(span)?; + } + Ok(acc) + } + /// Whether any item matches. pub fn any(&self, vm: &mut Vm, func: Func) -> SourceResult { for item in self.iter() { diff --git a/src/eval/methods.rs b/src/eval/methods.rs index 56d1c7b78..29b729cbe 100644 --- a/src/eval/methods.rs +++ b/src/eval/methods.rs @@ -105,6 +105,8 @@ pub fn call( "fold" => { array.fold(vm, args.expect("initial value")?, args.expect("function")?)? } + "sum" => array.sum(args.named("default")?, span)?, + "product" => array.product(args.named("default")?, span)?, "any" => Value::Bool(array.any(vm, args.expect("function")?)?), "all" => Value::Bool(array.all(vm, args.expect("function")?)?), "flatten" => Value::Array(array.flatten()), diff --git a/tests/ref/compiler/array.png b/tests/ref/compiler/array.png index a7c52f1accd9476a1368ad4c526ae10b7bb19f32..a96dfe649e5364e14a05ccbabf59569efb051993 100644 GIT binary patch literal 8385 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 B#(e+) diff --git a/tests/typ/compiler/array.typ b/tests/typ/compiler/array.typ index c9e85ed77..c52160b08 100644 --- a/tests/typ/compiler/array.typ +++ b/tests/typ/compiler/array.typ @@ -166,6 +166,27 @@ // Error: 20-22 unexpected argument #(1, 2, 3).fold(0, () => none) +--- +// Test the `sum` method. +#test(().sum(default: 0), 0) +#test(().sum(default: []), []) +#test((1, 2, 3).sum(), 6) + +--- +// Error: 2-10 cannot calculate sum of empty array with no default +#().sum() + +--- +// Test the `product` method. +#test(().product(default: 0), 0) +#test(().product(default: []), []) +#test(([ab], 3).product(), [ab]*3) +#test((1, 2, 3).product(), 6) + +--- +// Error: 2-14 cannot calculate product of empty array with no default +#().product() + --- // Test the `rev` method. #test(range(3).rev(), (2, 1, 0))