diff --git a/src/context/helper.rs b/src/context/helper.rs index 8e7a9a5..8e86e13 100644 --- a/src/context/helper.rs +++ b/src/context/helper.rs @@ -158,11 +158,33 @@ pub fn average(arg: &Value) -> EvalResult { total += if let Value::Float(float) = arg { float.clone() } else if let Value::Int(int) = arg { int.clone() as f64 } - else { todo!() }; + else { return Err(EvalexprError::expected_number(arg.clone())) }; } Ok( (total / len).into() ) - } else { todo!() } + } else { Err(EvalexprError::expected_tuple(arg.clone())) } +} + +pub fn median(arg: &Value) -> EvalResult { + if arg.is_tuple() { + let args = sort(arg).unwrap().as_tuple().unwrap(); + let len = args.len(); + let middle = len / 2; + if len % 2 != 0 { Ok(args[middle].as_number().unwrap().into()) } + else { + let left = args[middle - 1].as_number().unwrap(); + let right = args[middle].as_number().unwrap(); + Ok( ((left + right) / 2f64 ).into() ) + } + } else { Err(EvalexprError::expected_tuple(arg.clone())) } +} + +pub fn sort(arg: &Value) -> EvalResult { + if let Value::Tuple(args) = arg { + let mut args = args.clone(); + args.sort_by(|a, b| a.as_number().unwrap().total_cmp(&b.as_number().unwrap())); + Ok(args.into()) + } else { Err(EvalexprError::expected_tuple(arg.clone())) } } // Radix conversion diff --git a/src/context/mod.rs b/src/context/mod.rs index e6beeb6..7f76d29 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -38,6 +38,8 @@ pub fn build(args: &mut Arguments) -> HashMapContext { // data science functions "avg" => Function::new(|arg| helper::average(arg)), + "med" => Function::new(|arg| helper::median(arg)), + "sort" => Function::new(|arg| helper::sort(arg)), // radix functions "bin" => Function::new(|arg| helper::binary(arg)),