Fix up find/find_map.
This commit is contained in:
parent
6e40215631
commit
d94f362b51
@ -66,6 +66,7 @@ Enhancements
|
|||||||
* `FnPtr::iter_curry` and `FnPtr::iter_curry_mut` are added.
|
* `FnPtr::iter_curry` and `FnPtr::iter_curry_mut` are added.
|
||||||
* `Dynamic::deep_scan` is added to recursively scan for `Dynamic` values.
|
* `Dynamic::deep_scan` is added to recursively scan for `Dynamic` values.
|
||||||
* `>>` and `<<` operators on integers no longer throw errors when the number of bits to shift is out of bounds. Shifting by a negative number of bits simply reverses the shift direction.
|
* `>>` and `<<` operators on integers no longer throw errors when the number of bits to shift is out of bounds. Shifting by a negative number of bits simply reverses the shift direction.
|
||||||
|
* `find` and `find_map` are added for arrays.
|
||||||
|
|
||||||
|
|
||||||
Version 1.11.0
|
Version 1.11.0
|
||||||
|
@ -942,6 +942,150 @@ pub mod array_functions {
|
|||||||
|
|
||||||
Ok(-1 as INT)
|
Ok(-1 as INT)
|
||||||
}
|
}
|
||||||
|
/// Iterate through all the elements in the array, applying a `filter` function to each element
|
||||||
|
/// in turn, and return a copy of the first element that returns `true`. If no element returns
|
||||||
|
/// `true`, `()` is returned.
|
||||||
|
///
|
||||||
|
/// # Function Parameters
|
||||||
|
///
|
||||||
|
/// * `element`: copy of array element
|
||||||
|
/// * `index` _(optional)_: current index in the array
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rhai
|
||||||
|
/// let x = [1, 2, 3, 5, 8, 13];
|
||||||
|
///
|
||||||
|
/// print(x.find(|v| v > 3)); // prints 5: 5 > 3
|
||||||
|
///
|
||||||
|
/// x.find(|v| v > 13) ?? print("not found"); // prints "not found": nothing is > 13
|
||||||
|
///
|
||||||
|
/// print(x.find(|v, i| v * i > 13)); // prints 5: 3 * 5 > 13
|
||||||
|
/// ```
|
||||||
|
#[rhai_fn(return_raw, pure)]
|
||||||
|
pub fn find(ctx: NativeCallContext, array: &mut Array, filter: FnPtr) -> RhaiResult {
|
||||||
|
find_starting_from(ctx, array, filter, 0)
|
||||||
|
}
|
||||||
|
/// Iterate through all the elements in the array, starting from a particular `start` position,
|
||||||
|
/// applying a `filter` function to each element in turn, and return a copy of the first element
|
||||||
|
/// that returns `true`. If no element returns `true`, `()` is returned.
|
||||||
|
///
|
||||||
|
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
|
||||||
|
/// * If `start` < -length of array, position counts from the beginning of the array.
|
||||||
|
/// * If `start` ≥ length of array, `-1` is returned.
|
||||||
|
///
|
||||||
|
/// # Function Parameters
|
||||||
|
///
|
||||||
|
/// * `element`: copy of array element
|
||||||
|
/// * `index` _(optional)_: current index in the array
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rhai
|
||||||
|
/// let x = [1, 2, 3, 5, 8, 13];
|
||||||
|
///
|
||||||
|
/// print(x.find(|v| v > 1, 2)); // prints 3: 3 > 1
|
||||||
|
///
|
||||||
|
/// x.find(|v| v < 2, 3) ?? print("not found"); // prints "not found": nothing < 2 past index 3
|
||||||
|
///
|
||||||
|
/// x.find(|v| v > 1, 8) ?? print("not found"); // prints "not found": nothing found past end of array
|
||||||
|
///
|
||||||
|
/// print(x.find(|v| v > 1, -3)); // prints 5: -3 = start from index 4
|
||||||
|
///
|
||||||
|
/// print(x.find(|v| v > 0, -99)); // prints 1: -99 = start from beginning
|
||||||
|
///
|
||||||
|
/// print(x.find(|v, i| v * i > 6, 3)); // prints 5: 5 * 4 > 6
|
||||||
|
/// ```
|
||||||
|
#[rhai_fn(name = "find", return_raw, pure)]
|
||||||
|
pub fn find_starting_from(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
filter: FnPtr,
|
||||||
|
start: INT,
|
||||||
|
) -> RhaiResult {
|
||||||
|
let index = index_of_filter_starting_from(ctx, array, filter, start)?;
|
||||||
|
|
||||||
|
if index < 0 {
|
||||||
|
return Ok(Dynamic::UNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(get(array, index))
|
||||||
|
}
|
||||||
|
/// Iterate through all the elements in the array, applying a `mapper` function to each element
|
||||||
|
/// in turn, and return the first result that is not `()`. Otherwise, `()` is returned.
|
||||||
|
///
|
||||||
|
/// # Function Parameters
|
||||||
|
///
|
||||||
|
/// * `element`: copy of array element
|
||||||
|
/// * `index` _(optional)_: current index in the array
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rhai
|
||||||
|
/// let x = [#{alice: 1}, #{bob: 2}, #{clara: 3}];
|
||||||
|
///
|
||||||
|
/// print(x.find_map(|v| v.alice)); // prints 1
|
||||||
|
///
|
||||||
|
/// x.find_map(|v| v.dave) ?? print("not found"); // prints "not found"
|
||||||
|
/// ```
|
||||||
|
#[rhai_fn(return_raw, pure)]
|
||||||
|
pub fn find_map(ctx: NativeCallContext, array: &mut Array, filter: FnPtr) -> RhaiResult {
|
||||||
|
find_map_starting_from(ctx, array, filter, 0)
|
||||||
|
}
|
||||||
|
/// Iterate through all the elements in the array, starting from a particular `start` position,
|
||||||
|
/// applying a `mapper` function to each element in turn, and return the first result that is not `()`.
|
||||||
|
/// Otherwise, `()` is returned.
|
||||||
|
///
|
||||||
|
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
|
||||||
|
/// * If `start` < -length of array, position counts from the beginning of the array.
|
||||||
|
/// * If `start` ≥ length of array, `-1` is returned.
|
||||||
|
///
|
||||||
|
/// # Function Parameters
|
||||||
|
///
|
||||||
|
/// * `element`: copy of array element
|
||||||
|
/// * `index` _(optional)_: current index in the array
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rhai
|
||||||
|
/// let x = [#{alice: 1}, #{bob: 2}, #{bob: 3}, #{clara: 3}, #{alice: 0}, #{clara: 5}];
|
||||||
|
///
|
||||||
|
/// print(x.find_map(|v| v.alice, 2)); // prints 0
|
||||||
|
///
|
||||||
|
/// x.find_map(|v| v.bob, 4) ?? print("not found"); // prints "not found"
|
||||||
|
///
|
||||||
|
/// x.find_map(|v| v.alice, 8) ?? print("not found"); // prints "not found"
|
||||||
|
///
|
||||||
|
/// print(x.find_map(|v| v.bob, -4)); // prints 3: -4 = start from index 2
|
||||||
|
///
|
||||||
|
/// print(x.find_map(|v| v.alice, -99)); // prints 1: -99 = start from beginning
|
||||||
|
/// ```
|
||||||
|
#[rhai_fn(name = "find_map", return_raw, pure)]
|
||||||
|
pub fn find_map_starting_from(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
filter: FnPtr,
|
||||||
|
start: INT,
|
||||||
|
) -> RhaiResult {
|
||||||
|
if array.is_empty() {
|
||||||
|
return Ok(Dynamic::UNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (start, ..) = calc_offset_len(array.len(), start, 0);
|
||||||
|
|
||||||
|
for (i, item) in array.iter().enumerate().skip(start) {
|
||||||
|
let ex = [(i as INT).into()];
|
||||||
|
|
||||||
|
let value =
|
||||||
|
filter.call_raw_with_extra_args("find_map", &ctx, None, [item.clone()], ex)?;
|
||||||
|
|
||||||
|
if !value.is_unit() {
|
||||||
|
return Ok(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Dynamic::UNIT)
|
||||||
|
}
|
||||||
/// Return `true` if any element in the array that returns `true` when applied the `filter` function.
|
/// Return `true` if any element in the array that returns `true` when applied the `filter` function.
|
||||||
///
|
///
|
||||||
/// # Function Parameters
|
/// # Function Parameters
|
||||||
@ -1718,146 +1862,4 @@ pub mod array_functions {
|
|||||||
) -> RhaiResultOf<bool> {
|
) -> RhaiResultOf<bool> {
|
||||||
equals(ctx, array1, array2).map(|r| !r)
|
equals(ctx, array1, array2).map(|r| !r)
|
||||||
}
|
}
|
||||||
/// Iterate through all the elements in the array, applying a `filter` function to each element
|
|
||||||
/// in turn, and return a copy of the first element that returns `true`.
|
|
||||||
/// If no element returns `true`, `()` is returned.
|
|
||||||
///
|
|
||||||
/// # Function Parameters
|
|
||||||
///
|
|
||||||
/// * `element`: copy of array element
|
|
||||||
/// * `index` _(optional)_: current index in the array
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rhai
|
|
||||||
/// let x = [1, 2, 3, 5, 8, 13];
|
|
||||||
///
|
|
||||||
/// print(x.find(|v| v > 3)); // prints 5: 5 > 3
|
|
||||||
///
|
|
||||||
/// x.find(|v| v > 13) ?? print("not found"); // prints "not found": nothing is > 13
|
|
||||||
///
|
|
||||||
/// print(x.find(|v, i| v * i > 13)); // prints 5: 3 * 5 > 13
|
|
||||||
/// ```
|
|
||||||
#[rhai_fn(return_raw, pure)]
|
|
||||||
pub fn find(ctx: NativeCallContext, array: &mut Array, filter: FnPtr) -> RhaiResult {
|
|
||||||
find_starting_from(ctx, array, filter, 0)
|
|
||||||
}
|
|
||||||
/// Iterate through all the elements in the array, starting from a particular `start` position,
|
|
||||||
/// applying a `filter` function to each element in turn, and return a copy of the first
|
|
||||||
/// element that returns `true`. If no element returns `true`, `()` is returned.
|
|
||||||
///
|
|
||||||
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
|
|
||||||
/// * If `start` < -length of array, position counts from the beginning of the array.
|
|
||||||
/// * If `start` ≥ length of array, `-1` is returned.
|
|
||||||
///
|
|
||||||
/// # Function Parameters
|
|
||||||
///
|
|
||||||
/// * `element`: copy of array element
|
|
||||||
/// * `index` _(optional)_: current index in the array
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rhai
|
|
||||||
/// let x = [1, 2, 3, 5, 8, 13];
|
|
||||||
///
|
|
||||||
/// print(x.find(|v| v > 1, 2)); // prints 3: 3 > 1
|
|
||||||
///
|
|
||||||
/// x.find(|v| v < 2, 3) ?? print("not found"); // prints "not found": nothing < 2 past index 3
|
|
||||||
///
|
|
||||||
/// x.find(|v| v > 1, 8) ?? print("not found"); // prints "not found": nothing found past end of array
|
|
||||||
///
|
|
||||||
/// print(x.find(|v| v > 1, -3)); // prints 5: -3 = start from index 4
|
|
||||||
///
|
|
||||||
/// print(x.find(|v| v > 0, -99)); // prints 1: -99 = start from beginning
|
|
||||||
///
|
|
||||||
/// print(x.find(|v, i| v * i > 6, 3)); // prints 5: 5 * 4 > 6
|
|
||||||
/// ```
|
|
||||||
#[rhai_fn(name = "find", return_raw, pure)]
|
|
||||||
pub fn find_starting_from(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
filter: FnPtr,
|
|
||||||
start: INT,
|
|
||||||
) -> RhaiResult {
|
|
||||||
let index = index_of_filter_starting_from(ctx, array, filter, start)?;
|
|
||||||
|
|
||||||
if index < 0 {
|
|
||||||
return Ok(Dynamic::UNIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(get(array, index))
|
|
||||||
}
|
|
||||||
/// Iterate through all the elements in the array, applying a `mapper` function to each element
|
|
||||||
/// in turn, and return the first result that is not `()`.
|
|
||||||
/// If no result is not `()`, `()` is returned.
|
|
||||||
///
|
|
||||||
/// # Function Parameters
|
|
||||||
///
|
|
||||||
/// * `element`: copy of array element
|
|
||||||
/// * `index` _(optional)_: current index in the array
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rhai
|
|
||||||
/// let x = [#{alice: 1}, #{bob: 2}, #{clara: 3}];
|
|
||||||
///
|
|
||||||
/// print(x.find_map(|v| v.alice)); // prints 1
|
|
||||||
///
|
|
||||||
/// x.find_map(|v| v.dave) ?? print("not found"); // prints "not found"
|
|
||||||
/// ```
|
|
||||||
#[rhai_fn(return_raw, pure)]
|
|
||||||
pub fn find_map(ctx: NativeCallContext, array: &mut Array, filter: FnPtr) -> RhaiResult {
|
|
||||||
find_map_starting_from(ctx, array, filter, 0)
|
|
||||||
}
|
|
||||||
/// Iterate through all the elements in the array, starting from a particular `start` position,
|
|
||||||
/// applying a `mapper` function to each element in turn, and return the first result that is not `()`.
|
|
||||||
/// If no result is not `()`, `()` is returned.
|
|
||||||
///
|
|
||||||
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
|
|
||||||
/// * If `start` < -length of array, position counts from the beginning of the array.
|
|
||||||
/// * If `start` ≥ length of array, `-1` is returned.
|
|
||||||
///
|
|
||||||
/// # Function Parameters
|
|
||||||
///
|
|
||||||
/// * `element`: copy of array element
|
|
||||||
/// * `index` _(optional)_: current index in the array
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rhai
|
|
||||||
/// let x = [#{alice: 1}, #{bob: 2}, #{bob: 3}, #{clara: 3}, #{alice: 0}, #{clara: 5}];
|
|
||||||
///
|
|
||||||
/// print(x.find_map(|v| v.alice, 2)); // prints 0
|
|
||||||
///
|
|
||||||
/// x.find_map(|v| v.bob, 4) ?? print("not found"); // prints "not found"
|
|
||||||
///
|
|
||||||
/// x.find_map(|v| v.alice, 8) ?? print("not found"); // prints "not found"
|
|
||||||
///
|
|
||||||
/// print(x.find_map(|v| v.bob, -4)); // prints 3: -4 = start from index 2
|
|
||||||
///
|
|
||||||
/// print(x.find_map(|v| v.alice, -99)); // prints 1: -99 = start from beginning
|
|
||||||
/// ```
|
|
||||||
#[rhai_fn(name = "find_map", return_raw, pure)]
|
|
||||||
pub fn find_map_starting_from(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
filter: FnPtr,
|
|
||||||
start: INT,
|
|
||||||
) -> RhaiResult {
|
|
||||||
if array.is_empty() {
|
|
||||||
return Ok(Dynamic::UNIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (start, ..) = calc_offset_len(array.len(), start, 0);
|
|
||||||
|
|
||||||
for (i, item) in array.iter().enumerate().skip(start) {
|
|
||||||
let value = make_dual_arity_fn_ptr_call("find_map", &filter, &ctx, [item.clone()], i)?;
|
|
||||||
|
|
||||||
if !value.is_unit() {
|
|
||||||
return Ok(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Dynamic::UNIT)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user