Skip to main content

ganit_core/eval/functions/math/average/
mod.rs

1use crate::eval::coercion::to_number;
2use crate::eval::functions::check_arity;
3use crate::types::{ErrorKind, Value};
4
5pub fn average_fn(args: &[Value]) -> Value {
6    if let Some(err) = check_arity(args, 1, 255) {
7        return err;
8    }
9    let mut sum = 0.0_f64;
10    let mut count = 0usize;
11    for arg in args {
12        let scalars: Vec<&Value> = match arg {
13            Value::Array(elems) => elems.iter().collect(),
14            other => vec![other],
15        };
16        for scalar in scalars {
17            match to_number(scalar.clone()) {
18                Err(e) => return e,
19                Ok(n) => {
20                    sum += n;
21                    count += 1;
22                }
23            }
24        }
25    }
26    if count == 0 {
27        return Value::Error(ErrorKind::DivByZero);
28    }
29    let result = sum / count as f64;
30    if !result.is_finite() {
31        return Value::Error(ErrorKind::Num);
32    }
33    Value::Number(result)
34}
35
36#[cfg(test)]
37mod tests;