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

arrays, maps: add indexed variant of collection function and minor cleanup (#15948)

This commit is contained in:
ChAoS_UnItY
2022-10-03 15:42:36 +08:00
committed by GitHub
parent 5b59171a00
commit ffaca82ff8
4 changed files with 135 additions and 5 deletions

View File

@ -241,6 +241,42 @@ pub fn reduce<T>(list []T, reduce_op fn (t1 T, t2 T) T) ?T {
}
}
// reduce_indexed sets `acc = list[0]`, then successively calls `acc = reduce_op(idx, acc, elem)` for each remaining element in `list`.
// returns the accumulated value in `acc`.
// returns an error if the array is empty.
// See also: [fold_indexed](#fold_indexed).
pub fn reduce_indexed<T>(list []T, reduce_op fn (int, T, T) T) ?T {
if list.len == 0 {
return error('Cannot reduce array of nothing.')
} else {
mut value := list[0]
for i, e in list {
if i == 0 {
continue
} else {
value = reduce_op(i, value, e)
}
}
return value
}
}
// filter_indexed filters elements based on predicate function
// being invoked on each element with its index in the original array.
pub fn filter_indexed<T>(list []T, predicate fn (idx int, e T) bool) []T {
mut result := []T{cap: list.len}
for i, e in list {
if predicate(i, e) {
result << e
}
}
return result
}
// fold sets `acc = init`, then successively calls `acc = fold_op(acc, elem)` for each element in `list`.
// returns `acc`.
// Example:
@ -261,7 +297,19 @@ pub fn fold<T, R>(list []T, init R, fold_op fn (r R, t T) R) R {
return value
}
// flattens n + 1 dimensional array into n dimensional array
// fold_indexed sets `acc = init`, then successively calls `acc = fold_op(idx, acc, elem)` for each element in `list`.
// returns `acc`.
pub fn fold_indexed<T, R>(list []T, init R, fold_op fn (idx int, r R, t T) R) R {
mut value := init
for i, e in list {
value = fold_op(i, value, e)
}
return value
}
// flatten flattens n + 1 dimensional array into n dimensional array
// Example: arrays.flatten<int>([[1, 2, 3], [4, 5]]) // => [1, 2, 3, 4, 5]
pub fn flatten<T>(list [][]T) []T {
// calculate required capacity
@ -285,6 +333,42 @@ pub fn flatten<T>(list [][]T) []T {
return result
}
// flat_map creates a new array populated with the flattened result of calling transform function
// being invoked on each element of `list`.
pub fn flat_map<T, R>(list []T, transform fn (T) []R) []R {
mut result := [][]R{cap: list.len}
for v in list {
result << transform(v)
}
return flatten(result)
}
// flat_map_indexed creates a new array populated with the flattened result of calling the `transform` function
// being invoked on each element with its index in the original array.
pub fn flat_map_indexed<T, R>(list []T, transform fn (int, T) []R) []R {
mut result := [][]R{cap: list.len}
for i, v in list {
result << transform(i, v)
}
return flatten(result)
}
// map_indexed creates a new array populated with the result of calling the `transform` function
// being invoked on each element with its index in the original array.
pub fn map_indexed<T, R>(list []T, transform fn (int, T) R) []R {
mut result := []R{cap: list.len}
for i, v in list {
result << transform(i, v)
}
return result
}
// group_by groups together elements, for which the `grouping_op` callback produced the same result.
// Example: arrays.group_by<int, string>(['H', 'el', 'lo'], fn (v string) int { return v.len }) // => {1: ['H'], 2: ['el', 'lo']}
pub fn group_by<K, V>(list []V, grouping_op fn (v V) K) map[K][]V {