diff --git a/CHANGELOG.md b/CHANGELOG.md index f9b992fe..4826745c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Enhancements * Array methods now avoid cloning as much as possible (although most predicates will involve cloning anyway if passed a closure). * Array methods that take function pointers (e.g. closures) now optionally take the function name as a string. +* Array adds the `dedup` method. * Inlining is disabled for error-path functions because errors are exceptional and scripts usually fail completely when an error is encountered. Deprecated API's diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 0e3e533f..f80dea59 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -637,6 +637,43 @@ mod array_functions { Ok(true) } + #[rhai_fn(return_raw)] + pub fn dedup(ctx: NativeCallContext, array: &mut Array) -> Result<(), Box> { + dedup_with_fn_name(ctx, array, OP_EQUALS) + } + #[rhai_fn(name = "dedup", return_raw)] + pub fn dedup_by_comparer( + ctx: NativeCallContext, + array: &mut Array, + comparer: FnPtr, + ) -> Result<(), Box> { + if array.is_empty() { + return Ok(()); + } + + dedup_with_fn_name(ctx, array, comparer.fn_name()) + } + #[rhai_fn(name = "dedup", return_raw)] + fn dedup_with_fn_name( + ctx: NativeCallContext, + array: &mut Array, + comparer: &str, + ) -> Result<(), Box> { + if array.is_empty() { + return Ok(()); + } + + array.dedup_by(|x, y| { + let mut args = [x, &mut y.clone()]; + + ctx.call_fn_raw(comparer, true, false, &mut args) + .unwrap_or_else(|_| Dynamic::FALSE) + .as_bool() + .unwrap_or(false) + }); + + Ok(()) + } #[rhai_fn(name = "reduce", return_raw, pure)] pub fn reduce_with_fn_name( ctx: NativeCallContext,