mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Add sum and product to arrays (#966)
This commit is contained in:
parent
12129f0170
commit
efad1e71fa
@ -630,6 +630,20 @@ Folds all items into a single value using an accumulator function.
|
|||||||
and one for an item.
|
and one for an item.
|
||||||
- returns: any
|
- 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()
|
### any()
|
||||||
Whether the given function returns `{true}` for any item in the array.
|
Whether the given function returns `{true}` for any item in the array.
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ macro_rules! __array {
|
|||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use crate::__array as array;
|
pub use crate::__array as array;
|
||||||
|
use crate::eval::ops::{add, mul};
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use ecow::eco_vec;
|
pub use ecow::eco_vec;
|
||||||
|
|
||||||
@ -199,6 +200,40 @@ impl Array {
|
|||||||
Ok(acc)
|
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.
|
/// Whether any item matches.
|
||||||
pub fn any(&self, vm: &mut Vm, func: Func) -> SourceResult<bool> {
|
pub fn any(&self, vm: &mut Vm, func: Func) -> SourceResult<bool> {
|
||||||
for item in self.iter() {
|
for item in self.iter() {
|
||||||
|
@ -105,6 +105,8 @@ pub fn call(
|
|||||||
"fold" => {
|
"fold" => {
|
||||||
array.fold(vm, args.expect("initial value")?, args.expect("function")?)?
|
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")?)?),
|
"any" => Value::Bool(array.any(vm, args.expect("function")?)?),
|
||||||
"all" => Value::Bool(array.all(vm, args.expect("function")?)?),
|
"all" => Value::Bool(array.all(vm, args.expect("function")?)?),
|
||||||
"flatten" => Value::Array(array.flatten()),
|
"flatten" => Value::Array(array.flatten()),
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.2 KiB |
@ -166,6 +166,27 @@
|
|||||||
// Error: 20-22 unexpected argument
|
// Error: 20-22 unexpected argument
|
||||||
#(1, 2, 3).fold(0, () => none)
|
#(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 the `rev` method.
|
||||||
#test(range(3).rev(), (2, 1, 0))
|
#test(range(3).rev(), (2, 1, 0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user