1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

arrays: add map_of_counts/1, map_of_indexes/1 as well as index_of_first/2, index_of_last/2 utilities (#16618)

This commit is contained in:
Delyan Angelov 2022-12-09 00:37:07 +02:00 committed by GitHub
parent f365771499
commit 7091010a53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 103 additions and 0 deletions

View File

@ -358,3 +358,49 @@ fn test_array_append_empty_struct() {
array := [XYZ{}]
assert (XYZ{} in names) == true
}
fn test_index_of_first() {
// vfmt off
assert index_of_first([1], fn (idx int, x int) bool { return x == 0 }) == -1
assert index_of_first([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 0 }) == 2
assert index_of_first([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 4 }) == 0
// vfmt on
}
fn test_index_of_last() {
// vfmt off
assert index_of_last([1], fn (idx int, x int) bool { return x == 0 }) == -1
assert index_of_last([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 0 }) == 4
assert index_of_last([4, 5, 0, 7, 0, 9], fn (idx int, x int) bool { return x == 4 }) == 0
// vfmt on
}
fn test_map_of_indexes() {
// vfmt off
assert arrays.map_of_indexes([]int{}) == {}
assert arrays.map_of_indexes([1]) == {1: [0]}
assert arrays.map_of_indexes([1, 2, 3, 999]) == {1: [0], 2: [1], 3: [2], 999: [3]}
assert arrays.map_of_indexes([999, 1, 2, 3]) == {1: [1], 2: [2], 3: [3], 999: [0]}
assert arrays.map_of_indexes([1, 2, 3, 4, 4, 2, 1, 4, 4, 999]) == {1: [0, 6], 2: [1, 5], 3: [2], 4: [3, 4, 7, 8], 999: [9]}
//
assert arrays.map_of_indexes([]string{}) == {}
assert arrays.map_of_indexes(['abc']) == {'abc': [0]}
assert arrays.map_of_indexes(['abc', 'abc']) == {'abc': [0, 1]}
assert arrays.map_of_indexes(['abc', 'def', 'abc']) == {'abc': [0, 2], 'def': [1]}
// vfmt on
}
fn test_map_of_counts() {
// vfmt off
assert map_of_counts([]int{}) == {}
assert map_of_counts([1]) == {1: 1}
assert map_of_counts([1, 2, 3, 999]) == {1: 1, 2: 1, 3: 1, 999: 1}
assert map_of_counts([999, 1, 2, 3]) == {1: 1, 2: 1, 3: 1, 999: 1}
assert map_of_counts([1, 2, 3, 4, 4, 2, 1, 4, 4, 999]) == {1: 2, 2: 2, 3: 1, 4: 4, 999: 1}
//
assert map_of_counts([]string{}) == {}
assert map_of_counts(['abc']) == {'abc': 1}
assert map_of_counts(['abc', 'abc']) == {'abc': 2}
assert map_of_counts(['abc', 'def', 'abc']) == {'abc': 2, 'def': 1}
// vfmt on
}

28
vlib/arrays/index_of.v Normal file
View File

@ -0,0 +1,28 @@
module arrays
// index_of_first returns the index of the first element of `array`, for which the predicate
// function returns true.
// If predicate does not return true for any of the elements, then index_of_first will return -1.
// Example: arrays.index_of_first([4,5,0,7,0,9], fn(idx int, x int) bool { return x == 0 }) == 2
pub fn index_of_first[T](array []T, predicate fn (idx int, elem T) bool) int {
for i, e in array {
if predicate(i, e) {
return i
}
}
return -1
}
// index_of_last returns the index of the last element of `array`, for which the predicate
// function returns true.
// If predicate does not return true for any of the elements, then index_of_last will return -1.
// Example: arrays.index_of_last([4,5,0,7,0,9], fn(idx int, x int) bool { return x == 0 }) == 4
pub fn index_of_last[T](array []T, predicate fn (idx int, elem T) bool) int {
for i := array.len - 1; i >= 0; i-- {
e := array[i]
if predicate(i, e) {
return i
}
}
return -1
}

29
vlib/arrays/map_of.v Normal file
View File

@ -0,0 +1,29 @@
module arrays
// map_of_indexes returns a map, where each key is an unique value in `array`,
// and each value for that key is an array, containing the indexes in `array`,
// where that value has been found.
// Example: arrays.map_of_indexes([1,2,3,4,4,2,1,4,4,999]) == {1: [0, 6], 2: [1, 5], 3: [2], 4: [3, 4, 7, 8], 999: [9]}
pub fn map_of_indexes[T](array []T) map[T][]int {
mut result := map[T][]int{}
for i, e in array {
if _ := result[e] {
result[e] << i
} else {
result[e] = [i]
}
}
return result
}
// map_of_counts returns a map, where each key is an unique value in `array`,
// and each value for that key is how many times that value occures in `array`.
// It can be useful for building histograms of discrete measurements.
// Example: arrays.map_of_counts([1,2,3,4,4,2,1,4,4]) == {1: 2, 2: 2, 3: 1, 4: 4}
pub fn map_of_counts[T](array []T) map[T]int {
mut result := map[T]int{}
for e in array {
result[e]++
}
return result
}