mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
arrays: add more util functions and tests for them - find_first, find_last, join_to_string (#18784)
This commit is contained in:
parent
7d6e15fa66
commit
e7e5a07aa2
@ -1,5 +1,7 @@
|
|||||||
module arrays
|
module arrays
|
||||||
|
|
||||||
|
import strings
|
||||||
|
|
||||||
// Common arrays functions:
|
// Common arrays functions:
|
||||||
// - min / max - return the value of the minumum / maximum
|
// - min / max - return the value of the minumum / maximum
|
||||||
// - idx_min / idx_max - return the index of the first minumum / maximum
|
// - idx_min / idx_max - return the index of the first minumum / maximum
|
||||||
@ -664,3 +666,53 @@ pub fn carray_to_varray[T](c_array_data voidptr, items int) []T {
|
|||||||
unsafe { vmemcpy(v_array.data, c_array_data, total_size) }
|
unsafe { vmemcpy(v_array.data, c_array_data, total_size) }
|
||||||
return v_array
|
return v_array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find_first returns the first element that matches the given predicate
|
||||||
|
// returns `none`, if there is no match found
|
||||||
|
// Example: arrays.find_first([1, 2, 3, 4, 5], fn (arr int) bool { arr == 3}) // => 3
|
||||||
|
pub fn find_first[T](array []T, predicate fn (elem T) bool) ?T {
|
||||||
|
if array.len == 0 {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
for item in array {
|
||||||
|
if predicate(item) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
|
||||||
|
// find_last returns the last element that matches the given predicate
|
||||||
|
// returns `none`, if there is no match found
|
||||||
|
// Example: arrays.find_last([1, 2, 3, 4, 5], fn (arr int) bool { arr == 3}) // => 3
|
||||||
|
pub fn find_last[T](array []T, predicate fn (elem T) bool) ?T {
|
||||||
|
if array.len == 0 {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
for idx := array.len - 1; idx >= 0; idx-- {
|
||||||
|
item := array[idx]
|
||||||
|
if predicate(item) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
|
||||||
|
// join_to_string takes in a custom transform function and joins all elements into a string with
|
||||||
|
// the specified separator
|
||||||
|
[manualfree]
|
||||||
|
pub fn join_to_string[T](array []T, separator string, transform fn (elem T) string) string {
|
||||||
|
mut sb := strings.new_builder(array.len * 2)
|
||||||
|
defer {
|
||||||
|
unsafe { sb.free() }
|
||||||
|
}
|
||||||
|
for i, item in array {
|
||||||
|
x := transform(item)
|
||||||
|
sb.write_string(x)
|
||||||
|
unsafe { x.free() }
|
||||||
|
if i < array.len - 1 {
|
||||||
|
sb.write_string(separator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.str()
|
||||||
|
}
|
||||||
|
@ -404,3 +404,71 @@ fn test_map_of_counts() {
|
|||||||
assert map_of_counts(['abc', 'def', 'abc']) == {'abc': 2, 'def': 1}
|
assert map_of_counts(['abc', 'def', 'abc']) == {'abc': 2, 'def': 1}
|
||||||
// vfmt on
|
// vfmt on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FindTest {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
const test_structs = [FindTest{'one', 1}, FindTest{'two', 2},
|
||||||
|
FindTest{'three', 3}, FindTest{'one', 4}]
|
||||||
|
|
||||||
|
fn test_find_first() {
|
||||||
|
// element in array
|
||||||
|
a := [1, 2, 3, 4, 5]
|
||||||
|
assert find_first[int](a, fn (arr int) bool {
|
||||||
|
return arr == 3
|
||||||
|
})? == 3, 'find element couldnt find the right element'
|
||||||
|
|
||||||
|
// find struct
|
||||||
|
find_by_name := find_first(arrays.test_structs, fn (arr FindTest) bool {
|
||||||
|
return arr.name == 'one'
|
||||||
|
})?
|
||||||
|
assert find_by_name == FindTest{'one', 1}
|
||||||
|
|
||||||
|
// not found
|
||||||
|
if _ := find_first(arrays.test_structs, fn (arr FindTest) bool {
|
||||||
|
return arr.name == 'nothing'
|
||||||
|
})
|
||||||
|
{
|
||||||
|
assert false
|
||||||
|
} else {
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_find_last() {
|
||||||
|
// // element in array
|
||||||
|
a := [1, 2, 3, 4, 5]
|
||||||
|
assert find_last[int](a, fn (arr int) bool {
|
||||||
|
return arr == 3
|
||||||
|
})? == 3, 'find element couldnt find the right element'
|
||||||
|
|
||||||
|
// find struct
|
||||||
|
find_by_name := find_last(arrays.test_structs, fn (arr FindTest) bool {
|
||||||
|
return arr.name == 'one'
|
||||||
|
})?
|
||||||
|
assert find_by_name == FindTest{'one', 4}
|
||||||
|
|
||||||
|
// not found
|
||||||
|
if _ := find_last(arrays.test_structs, fn (arr FindTest) bool {
|
||||||
|
return arr.name == 'nothing'
|
||||||
|
})
|
||||||
|
{
|
||||||
|
assert false
|
||||||
|
} else {
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_join_to_string() {
|
||||||
|
assert join_to_string[FindTest](arrays.test_structs, ':', fn (it FindTest) string {
|
||||||
|
return it.name
|
||||||
|
}) == 'one:two:three:one'
|
||||||
|
assert join_to_string[FindTest](arrays.test_structs, '', fn (it FindTest) string {
|
||||||
|
return it.name
|
||||||
|
}) == 'onetwothreeone'
|
||||||
|
assert join_to_string[int]([]int{}, ':', fn (it int) string {
|
||||||
|
return '1'
|
||||||
|
}) == ''
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user