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

arrays: add chunk and window functions (#11476)

This commit is contained in:
ChAoS_UnItY 2021-09-13 21:13:32 +08:00 committed by GitHub
parent b9dfc89aa9
commit 2ced845e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 3 deletions

View File

@ -4,6 +4,9 @@ module arrays
// - min / max - return the value of the minumum / maximum
// - idx_min / idx_max - return the index of the first minumum / maximum
// - merge - combine two sorted arrays and maintain sorted order
// - chunk - chunk array to arrays with n elements
// - window - get snapshots of the window of the given size sliding along array with the given step, where each snapshot is an array
// - zip - concat two arrays into one map
// min returns the minimum
pub fn min<T>(a []T) T {
@ -124,3 +127,56 @@ pub fn group<T>(lists ...[]T) [][]T {
return [][]T{}
}
// chunk array to arrays with n elements
// example: arrays.chunk([1, 2, 3], 2) => [[1, 2], [3]]
pub fn chunk<T>(list []T, size int) [][]T {
// allocate chunk array
mut chunks := [][]T{cap: list.len / size + if list.len % size == 0 { 0 } else { 1 }}
for i := 0; true; {
// check chunk size is greater than remaining element size
if list.len < i + size {
// check if there's no more element to chunk
if list.len <= i {
break
}
chunks << list[i..]
break
}
chunks << list[i..i + size]
i += size
}
return chunks
}
pub struct WindowAttribute {
size int
step int = 1
}
// get snapshots of the window of the given size sliding along array with the given step, where each snapshot is an array.
// - `size` - snapshot size
// - `step` - gap size between each snapshot, default is 1.
// example A: arrays.window([1, 2, 3, 4], size: 2) => [[1, 2], [2, 3], [3, 4]]
// example B: arrays.window([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], size: 3, step: 2) => [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]]
pub fn window<T>(list []T, attr WindowAttribute) [][]T {
// allocate snapshot array
mut windows := [][]T{cap: list.len - attr.size + 1}
for i := 0; true; {
// check remaining elements size is less than snapshot size
if list.len < i + attr.size {
break
}
windows << list[i..i + attr.size]
i += attr.step
}
return windows
}

View File

@ -85,3 +85,24 @@ fn test_group() {
assert z2 == [[8, 2], [9, 1]]
assert group<int>(x, []int{}) == [][]int{}
}
fn test_chunk() {
x := [1, 2, 3, 4, 5]
y := ['a', 'b', 'c', 'd', 'e', 'f']
z1 := chunk<int>(x, 2)
assert z1 == [[1, 2], [3, 4], [5]]
z2 := chunk<string>(y, 3)
assert z2 == [['a', 'b', 'c'], ['d', 'e', 'f']]
assert chunk<int>([]int{}, 2) == [][]int{}
}
fn test_window() {
x := [1, 2, 3, 4, 5, 6]
assert window<int>(x, size: 3) == [[1, 2, 3], [2, 3, 4], [3, 4, 5],
[4, 5, 6],
]
assert window<int>(x, size: 3, step: 2) == [[1, 2, 3], [3, 4, 5]]
assert window<int>([]int{}, size: 2) == [][]int{}
}

View File

@ -72,9 +72,6 @@ pub fn get_uchar(s string, index int) int {
return res
}
// raw_index - get the raw chracter from the string by the given index value.
// example: '我是V Lang'.raw_index(1) => '是'
// raw_index - get the raw chracter from the string by the given index value.
// example: utf8.raw_index('我是V Lang', 1) => '是'
pub fn raw_index(s string, index int) string {