-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ab9902
commit d772409
Showing
14 changed files
with
493 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package hash | ||
|
||
// Chunk 将哈希表按照指定大小分块 | ||
// - m: 待分块的哈希表 | ||
// - size: 每块的大小 | ||
func Chunk[K comparable, V any](m map[K]V, size int) []map[K]V { | ||
if len(m) == 0 { | ||
return nil | ||
} | ||
|
||
var ( | ||
i int | ||
j int | ||
) | ||
chunks := make([]map[K]V, (len(m)-1)/size+1) | ||
for i = 0; i < len(m); i += size { | ||
chunks[j] = make(map[K]V, size) | ||
for key, value := range m { | ||
if i <= j*size && j*size < i+size { | ||
chunks[j][key] = value | ||
} | ||
} | ||
j++ | ||
} | ||
|
||
return chunks | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package hash | ||
|
||
// RandomDrop 随机删除哈希表中的指定数量的元素 | ||
// - 该函数会修改原哈希表,如果不想修改原哈希表,请使用 RandomDropCopy | ||
func RandomDrop[K comparable, V any](n int, hash map[K]V) map[K]V { | ||
if n <= 0 || len(hash) <= n { | ||
return hash | ||
} | ||
for k := range hash { | ||
if n <= 0 { | ||
break | ||
} | ||
delete(hash, k) | ||
n-- | ||
} | ||
return hash | ||
} | ||
|
||
// RandomDropCopy 随机删除哈希表中的指定数量的元素 | ||
// - 该函数不会修改原哈希表,如果想修改原哈希表,请使用 RandomDrop | ||
func RandomDropCopy[K comparable, V any](n int, m map[K]V) map[K]V { | ||
if n <= 0 || len(m) <= n { | ||
return map[K]V{} | ||
} | ||
var nm = make(map[K]V, len(m)) | ||
for k, v := range m { | ||
if n <= 0 { | ||
break | ||
} | ||
nm[k] = v | ||
n-- | ||
} | ||
return nm | ||
} | ||
|
||
// DropBy 从哈希表中删除指定的元素 | ||
func DropBy[K comparable, V any](m map[K]V, fn func(key K, value V) bool) map[K]V { | ||
for k, v := range m { | ||
if fn(k, v) { | ||
delete(m, k) | ||
} | ||
} | ||
return m | ||
} | ||
|
||
// DropByCopy 与 DropBy 功能相同,但是该函数不会修改原哈希表 | ||
func DropByCopy[K comparable, V any](m map[K]V, fn func(key K, value V) bool) map[K]V { | ||
var nm = make(map[K]V, len(m)) | ||
for k, v := range m { | ||
if fn(k, v) { | ||
continue | ||
} | ||
nm[k] = v | ||
} | ||
return nm | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package hash | ||
|
||
// Each 根据传入的 abort 遍历 m,如果 iterator 返回值与 abort 相同,则停止遍历 | ||
func Each[K comparable, V any](abort bool, m map[K]V, iterator func(i int, key K, item V) bool) { | ||
i := 0 | ||
for k, v := range m { | ||
if iterator(i, k, v) == abort { | ||
break | ||
} | ||
i++ | ||
} | ||
} | ||
|
||
// EachT 与 Each 的功能相同,但是 abort 被默认为 true | ||
func EachT[K comparable, V any](m map[K]V, iterator func(i int, key K, item V) bool) { | ||
Each(true, m, iterator) | ||
} | ||
|
||
// EachF 与 Each 的功能相同,但是 abort 被默认为 false | ||
func EachF[K comparable, V any](m map[K]V, iterator func(i int, key K, item V) bool) { | ||
Each(false, m, iterator) | ||
} | ||
|
||
// EachResult 根据传入的 abort 遍历 m,得到遍历的结果,如果 iterator 返回值中的 bool 值与 abort 相同,则停止遍历,并返回当前已积累的结果 | ||
func EachResult[K comparable, V any, R any](abort bool, m map[K]V, iterator func(i int, key K, item V) (R, bool)) []R { | ||
var result []R | ||
i := 0 | ||
for k, v := range m { | ||
r, ok := iterator(i, k, v) | ||
result = append(result, r) | ||
if ok == abort { | ||
break | ||
} | ||
i++ | ||
} | ||
return result | ||
} | ||
|
||
// EachResultT 与 EachResult 的功能相同,但是 abort 被默认为 true | ||
func EachResultT[K comparable, V any, R any](m map[K]V, iterator func(i int, key K, item V) (R, bool)) []R { | ||
return EachResult(true, m, iterator) | ||
} | ||
|
||
// EachResultF 与 EachResult 的功能相同,但是 abort 被默认为 false | ||
func EachResultF[K comparable, V any, R any](m map[K]V, iterator func(i int, key K, item V) (R, bool)) []R { | ||
return EachResult(false, m, iterator) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package hash | ||
|
||
// Filter 根据特定的表达式过滤哈希表成员 | ||
// - reserve: 是否保留符合条件的成员 | ||
// - m: 待过滤的哈希表 | ||
// - expression: 过滤表达式 | ||
// | ||
// 这个函数的作用是遍历输入哈希表 m,然后根据 expression 函数的返回值来决定是否保留每个元素。具体来说 | ||
// - 如果 expression 返回 true 并且 reserve 也是 true,那么元素会被保留 | ||
// - 如果 expression 返回 false 并且 reserve 是 false,那么元素也会被保留 | ||
// | ||
// 该没有创建新的内存空间或进行元素复制,所以整个操作相当高效。同时,由于 m 和 map 实际上共享底层的数组,因此这个函数会改变传入的 map。如果不希望改变原哈希表,需要在函数调用之前手动复制一份或者使用 FilterCopy 函数。 | ||
func Filter[K comparable, V any](reserve bool, m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
if len(m) == 0 { | ||
return m | ||
} | ||
|
||
for key, value := range m { | ||
if !expression(key, value) { | ||
delete(m, key) | ||
} | ||
} | ||
|
||
return m | ||
} | ||
|
||
// FilterT 与 Filter 的功能相同,但是 reserve 被默认为 true | ||
func FilterT[K comparable, V any](m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
return Filter(true, m, expression) | ||
} | ||
|
||
// FilterF 与 Filter 的功能相同,但是 reserve 被默认为 false | ||
func FilterF[K comparable, V any](m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
return Filter(false, m, expression) | ||
} | ||
|
||
// FilterCopy 与 Filter 的功能相同,但是不会改变原哈希表,而是返回一个新的哈希表 | ||
func FilterCopy[K comparable, V any](reserve bool, m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
var res = map[K]V{} | ||
for key, value := range m { | ||
if expression(key, value) { | ||
res[key] = value | ||
} | ||
} | ||
return res | ||
} | ||
|
||
// FilterTCopy 与 FilterCopy 的功能相同,但是 reserve 被默认为 true | ||
func FilterTCopy[K comparable, V any](m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
return FilterCopy(true, m, expression) | ||
} | ||
|
||
// FilterFCopy 与 FilterCopy 的功能相同,但是 reserve 被默认为 false | ||
func FilterFCopy[K comparable, V any](m map[K]V, expression func(key K, value V) bool) map[K]V { | ||
return FilterCopy(false, m, expression) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package slice | ||
|
||
// Chunk 返回分块后的切片 | ||
func Chunk[T any](collection []T, size int) [][]T { | ||
if len(collection) == 0 { | ||
return nil | ||
} | ||
|
||
if size < 1 { | ||
panic("size must be greater than 0") | ||
} | ||
|
||
result := make([][]T, 0, (len(collection)+size-1)/size) | ||
for size < len(collection) { | ||
collection, result = collection[size:], append(result, collection[0:size]) | ||
} | ||
return append(result, collection) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package slice | ||
|
||
// Drop 从切片中删除指定数量的元素 | ||
// - start: 起始位置 | ||
// - n: 删除的元素数量 | ||
// - slice: 待删除元素的切片 | ||
// | ||
// 关于 start 的取值: | ||
// - 当 start < 0 时,start 将会从右至左计数,即 -1 表示最后一个元素,-2 表示倒数第二个元素,以此类推 | ||
func Drop[V any](start, n int, slice []V) []V { | ||
var s = make([]V, len(slice)) | ||
copy(s, slice) | ||
if start < 0 { | ||
start = len(s) + start - n + 1 | ||
if start < 0 { | ||
start = 0 | ||
} | ||
} | ||
|
||
end := start + n | ||
if end > len(s) { | ||
end = len(s) | ||
} | ||
|
||
return append(s[:start], s[end:]...) | ||
} | ||
|
||
// DropBy 从切片中删除指定的元素 | ||
// - slice: 待删除元素的切片 | ||
func DropBy[V any](slice []V, fn func(index int, value V) bool) []V { | ||
var s = make([]V, len(slice)) | ||
copy(s, slice) | ||
for i := 0; i < len(s); i++ { | ||
if fn(i, s[i]) { | ||
s = append(s[:i], s[i+1:]...) | ||
i-- | ||
} | ||
} | ||
return s | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package slice_test | ||
|
||
import ( | ||
"github.com/kercylan98/minotaur/utils/slice" | ||
"testing" | ||
) | ||
|
||
func TestDrop(t *testing.T) { | ||
s := []int{1, 2, 3, 4, 5} | ||
t.Log(s, slice.Drop(1, 3, s)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package slice | ||
|
||
// Each 根据传入的 abort 遍历 slice,如果 iterator 返回值与 abort 相同,则停止遍历 | ||
func Each[V any](abort bool, slice []V, iterator func(index int, item V) bool) { | ||
for i := 0; i < len(slice); i++ { | ||
if iterator(i, slice[i]) == abort { | ||
break | ||
} | ||
} | ||
} | ||
|
||
// EachT 与 Each 的功能相同,但是 abort 被默认为 true | ||
func EachT[V any](slice []V, iterator func(index int, item V) bool) { | ||
Each(true, slice, iterator) | ||
} | ||
|
||
// EachF 与 Each 的功能相同,但是 abort 被默认为 false | ||
func EachF[V any](slice []V, iterator func(index int, item V) bool) { | ||
Each(false, slice, iterator) | ||
} | ||
|
||
// EachReverse 根据传入的 abort 从后往前遍历 slice,如果 iterator 返回值与 abort 相同,则停止遍历 | ||
func EachReverse[V any](abort bool, slice []V, iterator func(index int, item V) bool) { | ||
for i := len(slice) - 1; i >= 0; i-- { | ||
if iterator(i, slice[i]) == abort { | ||
break | ||
} | ||
} | ||
} | ||
|
||
// EachReverseT 与 EachReverse 的功能相同,但是 abort 被默认为 true | ||
func EachReverseT[V any](slice []V, iterator func(index int, item V) bool) { | ||
EachReverse(true, slice, iterator) | ||
} | ||
|
||
// EachReverseF 与 EachReverse 的功能相同,但是 abort 被默认为 false | ||
func EachReverseF[V any](slice []V, iterator func(index int, item V) bool) { | ||
EachReverse(false, slice, iterator) | ||
} | ||
|
||
// EachResult 根据传入的 abort 遍历 slice,得到遍历的结果,如果 iterator 返回值中的 bool 值与 abort 相同,则停止遍历,并返回当前已积累的结果 | ||
func EachResult[V any, R any](abort bool, slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
var result []R | ||
for i := 0; i < len(slice); i++ { | ||
r, ok := iterator(i, slice[i]) | ||
result = append(result, r) | ||
if ok == abort { | ||
break | ||
} | ||
} | ||
return result | ||
} | ||
|
||
// EachResultT 与 EachResult 的功能相同,但是 abort 被默认为 true | ||
func EachResultT[V any, R any](slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
return EachResult(true, slice, iterator) | ||
} | ||
|
||
// EachResultF 与 EachResult 的功能相同,但是 abort 被默认为 false | ||
func EachResultF[V any, R any](slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
return EachResult(false, slice, iterator) | ||
} | ||
|
||
// EachResultReverse 根据传入的 abort 从后往前遍历 slice,得到遍历的结果,如果 iterator 返回值中的 bool 值与 abort 相同,则停止遍历,并返回当前已积累的结果 | ||
func EachResultReverse[V any, R any](abort bool, slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
var result []R | ||
for i := len(slice) - 1; i >= 0; i-- { | ||
r, ok := iterator(i, slice[i]) | ||
result = append(result, r) | ||
if ok == abort { | ||
break | ||
} | ||
} | ||
return result | ||
} | ||
|
||
// EachResultReverseT 与 EachResultReverse 的功能相同,但是 abort 被默认为 true | ||
func EachResultReverseT[V any, R any](slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
return EachResultReverse(true, slice, iterator) | ||
} | ||
|
||
// EachResultReverseF 与 EachResultReverse 的功能相同,但是 abort 被默认为 false | ||
func EachResultReverseF[V any, R any](slice []V, iterator func(index int, item V) (R, bool)) []R { | ||
return EachResultReverse(false, slice, iterator) | ||
} |
Oops, something went wrong.