forked from synapsecns/sanguine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
slice.go
59 lines (47 loc) · 1.38 KB
/
slice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package core
import (
"crypto/rand"
"encoding/binary"
"fmt"
)
// RandomItem is a generic function to get a random item from a slice.
func RandomItem[T any](items []T) (res T, _ error) {
if len(items) == 0 {
return res, fmt.Errorf("empty slice")
}
index, err := randInt(len(items))
if err != nil {
return res, fmt.Errorf("error generating random index: %w", err)
}
return items[index], nil
}
// randInt generates a random integer between 0 (inclusive) and max (exclusive).
func randInt(max int) (int, error) {
var buf [4]byte
if _, err := rand.Read(buf[:]); err != nil {
return 0, fmt.Errorf("error reading random bytes: %w", err)
}
// Interpret the buffer as an uint32 and convert to int.
n := int(binary.BigEndian.Uint32(buf[:]))
// Limit the range to [0, max).
return n % max, nil
}
// ChunkSlice takes a slice of any ordered type (like int, float64, string, etc.)
// and divides it into chunks of a specified size.
func ChunkSlice[T any](slice []T, chunkSize int) [][]T {
var chunks [][]T
for i := 0; i < len(slice); i += chunkSize {
end := i + chunkSize
// necessary check to avoid slicing beyond
// slice capacity
if end > len(slice) {
end = len(slice)
}
chunks = append(chunks, slice[i:end])
}
return chunks
}
// ToSlice converts any number of items of any type to a slice containing those items.
func ToSlice[T any](items ...T) []T {
return items
}