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
|
||||
|
||||
import strings
|
||||
|
||||
// Common arrays functions:
|
||||
// - min / max - return the value of the 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) }
|
||||
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}
|
||||
// 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