summaryrefslogtreecommitdiff
path: root/src/eval/array.rs
diff options
context:
space:
mode:
authorSekoiaTree <51149447+SekoiaTree@users.noreply.github.com>2023-04-25 11:18:27 +0200
committerGitHub <noreply@github.com>2023-04-25 11:18:27 +0200
commitefad1e71fa699e0d2413d3a6a3ce5a4163e38112 (patch)
tree64dd37c540989e71408ee005abdccdb523d76618 /src/eval/array.rs
parent12129f01707a3389ef90a4c78a872e1c7897a752 (diff)
Add sum and product to arrays (#966)
Diffstat (limited to 'src/eval/array.rs')
-rw-r--r--src/eval/array.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/eval/array.rs b/src/eval/array.rs
index b04fdab8..1166ce94 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<Value>, span: Span) -> SourceResult<Value> {
+ 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<Value>, span: Span) -> SourceResult<Value> {
+ 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<bool> {
for item in self.iter() {