Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alvii147/gloop
Go utility library for convenient looping using the range-over-func feature
https://github.com/alvii147/gloop
golang
Last synced: 11 days ago
JSON representation
Go utility library for convenient looping using the range-over-func feature
- Host: GitHub
- URL: https://github.com/alvii147/gloop
- Owner: alvii147
- License: mit
- Created: 2024-10-25T00:47:27.000Z (13 days ago)
- Default Branch: main
- Last Pushed: 2024-10-25T11:20:43.000Z (12 days ago)
- Last Synced: 2024-10-26T13:59:33.381Z (11 days ago)
- Topics: golang
- Language: Go
- Homepage:
- Size: 165 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Genocide Watch](https://hinds-banner.vercel.app/genocide-watch?variant=crimson)](https://www.pcrf.net/)
gloop is a Go utility library for convenient looping using the range-over-func feature.## Installation
```bash
go get github.com/alvii147/gloop
```> [!NOTE]
> Go version 1.23+ required as older versions don't offer the range-over-func feature.## Features
* [Generators](#generators)
* [Interval](#interval)
* [Linspace](#linspace)
* [Scalar Iterators](#scalar-iterators)
* [Chain](#chain)
* [Channel](#channel)
* [Enumerate](#enumerate)
* [Filter](#filter)
* [List](#list)
* [Reverse](#reverse)
* [Slice](#slice)
* [String](#string)
* [Transform](#transform)
* [Zip](#zip)
* [Vector Iterators](#vector-iterators)
* [Batch](#batch)
* [Cartesian Product](#cartesian-product)
* [Combinations](#combinations)
* [Permutations](#permutations)
* [Window](#window)
* [Accumulators](#accumulators)
* [All](#all)
* [Any](#any)
* [Max](#max)
* [Mean](#mean)
* [Min](#min)
* [Product](#product)
* [Reduce](#reduce)
* [Sum](#sum)
* [To List](#to-list)
* [To Slice](#to-slice)
* [To String](#to-string)
* [Parallelizers](#parallelizers)
* [Parallelize](#parallelize)## Generators
### Interval
`Interval` allows a for loop to range over values in a given interval with a given step size.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
for i := range gloop.Interval(3, 9, 2) {
fmt.Println(i)
}
}
``````
3
5
7
````WithIntervalClosed` can be used to configure the interval as closed so the end point value is included.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
for i := range gloop.Interval(3, 9, 2, gloop.WithIntervalClosed(true)) {
fmt.Println(i)
}
}
``````
3
5
7
9
```### Linspace
`Linspace` allows a for loop to range over evenly spaced values within a given interval.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
for i := range gloop.Linspace(2, 3, 5) {
fmt.Println(i)
}
}
``````
2
2.25
2.5
2.75
````WithLinspaceClosed` can be used to configure the interval as closed so the end point value is included.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
for i := range gloop.Linspace(2, 3, 5, gloop.WithLinspaceClosed(true)) {
fmt.Println(i)
}
}
``````
2
2.25
2.5
2.75
3
```## Scalar Iterators
### Chain
`Chain` allows a for loop to range over multiple sequences.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values1 := []int{3, 1, 4}
values2 := []int{1, 6}
for i := range gloop.Chain(gloop.Slice(values1), gloop.Slice(values2)) {
fmt.Println(i)
}
}
``````
3
1
4
1
6
```### Channel
`Channel` allows a for loop to receive and range over values from a given channel.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
ch := make(chan int)
go func() {
ch <- 3
ch <- 1
ch <- 4
close(ch)
}()for i := range gloop.Channel(ch) {
fmt.Println(i)
}
}
``````
3
1
4
```### Enumerate
`Enumerate` allows a for loop to iterate over a sequence with an index.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
ch := make(chan int)
go func() {
ch <- 3
ch <- 1
ch <- 4
close(ch)
}()for i, value := range gloop.Enumerate(gloop.Channel(ch)) {
fmt.Println(i, value)
}
}
``````
0 3
1 1
2 4
```### Filter
`Filter` runs a given function on each value from a given sequence and allows a for loop to range over values for which the function returns true.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func isOdd(i int) bool {
return i%2 == 1
}func main() {
values := []int{3, 1, 4}
for i := range gloop.Filter(gloop.Slice(values), isOdd) {
fmt.Println(i)
}
}
``````
3
1
```### List
`List` allows a for loop to range over a given list from [container/list](https://pkg.go.dev/container/list).
```go
package mainimport (
"container/list"
"fmt""github.com/alvii147/gloop"
)func main() {
l := list.New()
l.PushBack(3)
l.PushBack(1)
l.PushBack(4)for elem := range gloop.List(l) {
fmt.Println(elem.Value)
}
}
``````
3
1
4
```### Reverse
`Reverse` allows a for loop to range over a given sequence in order of descending index.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4}
for i := range gloop.Reverse(gloop.Slice(values)) {
fmt.Println(i)
}
}
``````
4
1
3
```### Slice
`Slice` allows a for loop to range over a given slice.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4}
for i := range gloop.Slice(values) {
fmt.Println(i)
}
}
``````
3
1
4
```### String
`String` allows a for loop to range over the runes in a given string.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
for r := range gloop.String("CAT") {
fmt.Println(string(r))
}
}
``````
C
A
T
```### Transform
`Transform` runs a given function on each value from a given sequence and allows a for loop to range over the returned values.
```go
package mainimport (
"fmt"
"strings""github.com/alvii147/gloop"
)func main() {
values := []string{"CaT", "dOg"}
for s := range gloop.Transform(gloop.Slice(values), strings.ToLower) {
fmt.Println(s)
}
}
``````
cat
dog
```### Zip
`Zip` allows a for loop to iterate over two given sequences in pairs.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values1 := []int{3, 1, 4}
values2 := []int{1, 5, 9}
for value1, value2 := range gloop.Zip(gloop.Slice(values1), gloop.Slice(values2)) {
fmt.Println(value1, value2)
}
}
``````
3 1
1 5
4 9
```By default, iteration terminates when the shorter sequence is exhaused.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values1 := []int{3, 1, 4}
values2 := []int{1, 5, 9, 2, 6, 5}
for value1, value2 := range gloop.Zip(gloop.Slice(values1), gloop.Slice(values2)) {
fmt.Println(value1, value2)
}
}
``````
3 1
1 5
4 9
````WithZipPadded` can be used to configured iteration to continue till the longer sequence is exhaused with the shorter sequence padded with zero-values.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values1 := []int{3, 1, 4}
values2 := []int{1, 5, 9, 2, 6, 5}
for value1, value2 := range gloop.Zip(
gloop.Slice(values1),
gloop.Slice(values2),
gloop.WithZipPadded[int, int](true),
) {
fmt.Println(value1, value2)
}
}
``````
3 1
1 5
4 9
0 2
0 6
0 5
````WithZipPadValue1` can be used to set the padding value for the shorter sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values1 := []int{3, 1, 4}
values2 := []int{1, 5, 9, 2, 6, 5}
for value1, value2 := range gloop.Zip(
gloop.Slice(values1),
gloop.Slice(values2),
gloop.WithZipPadded[int, int](true),
gloop.WithZipPadValue1[int, int](-1),
) {
fmt.Println(value1, value2)
}
}
``````
3 1
1 5
4 9
-1 2
-1 6
-1 5
```## Vector Iterators
### Batch
`Batch` allows a for loop to range over a given sequence in batches of a given size.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4, 1, 5, 9, 2, 6, 5}
for seq := range gloop.Batch(gloop.Slice(values), 3) {
batch := gloop.ToSlice(seq)
fmt.Println(batch)
}
}
``````
[3 1 4]
[1 5 9]
[2 6 5]
```### Cartesian Product
`CartesianProduct` allows a for loop to range over the Cartesian product of a given size for a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
s := "CAT"
for seq := range gloop.CartesianProduct(gloop.String(s), 2) {
product := gloop.ToString(seq)
fmt.Println(product)
}
}
``````
CC
CA
CT
AC
AA
AT
TC
TA
TT
```### Combinations
`Combinations` allows a for loop to range over all combinations of a given size for a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
s := "CAT"
for seq := range gloop.Combinations(gloop.String(s), 2) {
comb := gloop.ToString(seq)
fmt.Println(comb)
}
}
``````
CA
CT
AT
```### Permutations
`Permutations` allows a for loop to range over all permutations of a given size for a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
s := "CAT"
for seq := range gloop.Permutations(gloop.String(s), 2) {
perm := gloop.ToString(seq)
fmt.Println(perm)
}
}
``````
CA
CT
AC
AT
TC
TA
```### Window
`Window` allows a for loop to range over a given sequence in sliding windows of a given size.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4, 1, 5, 9}
for seq := range gloop.Window(gloop.Slice(values), 3) {
window := gloop.ToSlice(seq)
fmt.Println(window)
}
}
``````
[3 1 4]
[1 4 1]
[4 1 5]
[1 5 9]
```## Accumulators
### All
`All` computes whether or not all values in a sequence are true.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
allTrue := []bool{true, true, true}
someTrue := []bool{true, false, true}
allFalse := []bool{false, false, false}fmt.Println(gloop.All(gloop.Slice(allTrue)))
fmt.Println(gloop.All(gloop.Slice(someTrue)))
fmt.Println(gloop.All(gloop.Slice(allFalse)))
}
``````
true
false
false
```### Any
`Any` computes whether or not any value in a sequence is true.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
allTrue := []bool{true, true, true}
someTrue := []bool{true, false, true}
allFalse := []bool{false, false, false}fmt.Println(gloop.Any(gloop.Slice(allTrue)))
fmt.Println(gloop.Any(gloop.Slice(someTrue)))
fmt.Println(gloop.Any(gloop.Slice(allFalse)))
}
``````
true
true
false
```### Max
`Max` computes the maximum value over a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4, 2}
maxValue := gloop.Max(gloop.Slice(values))
fmt.Println(maxValue)
}
``````
4
```### Mean
`Mean` computes the mean value over a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4, 2}
mean := gloop.Mean(gloop.Slice(values))
fmt.Println(mean)
}
``````
2.5
```### Min
`Min` computes the minumum value over a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4, 2}
minValue := gloop.Min(gloop.Slice(values))
fmt.Println(minValue)
}
``````
1
```### Product
`Product` executes the product of values a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4}
prod := gloop.Product(gloop.Slice(values))
fmt.Println(prod)
}
``````
12
```### Reduce
`Reduce` runs a given function on each value from a given sequence and accumulates the result into a single value.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func add(a, b int) int {
return a + b
}func main() {
values := []int{3, 1, 4}
sum := gloop.Reduce(gloop.Slice(values), add)
fmt.Println(sum)
}
``````
8
````WithReduceInitialValue` can be used to set the initial value of the accumulator.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func multiply(a, b int) int {
return a * b
}func main() {
values := []int{3, 1, 4}
product := gloop.Reduce(gloop.Slice(values), multiply, gloop.WithReduceInitialValue(1))
fmt.Println(product)
}
``````
12
```### Sum
`Sum` executes summation over a given sequence.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
values := []int{3, 1, 4}
sum := gloop.Sum(gloop.Slice(values))
fmt.Println(sum)
}
``````
8
```### To List
`ToList` converts a sequence to a list from [container/list](https://pkg.go.dev/container/list).
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
seq := func(yield func(int) bool) {
yield(3)
yield(1)
yield(4)
}l := gloop.ToList(seq)
fmt.Println(l.Remove(l.Front()))
fmt.Println(l.Remove(l.Front()))
fmt.Println(l.Remove(l.Front()))
}
``````
3
1
4
```### To Slice
`ToSlice` converts a sequence to a slice.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
seq := func(yield func(int) bool) {
yield(3)
yield(1)
yield(4)
}fmt.Println(gloop.ToSlice(seq))
}
``````
[3 1 4]
```### To String
`ToString` converts a sequence of runes to a string.
```go
package mainimport (
"fmt""github.com/alvii147/gloop"
)func main() {
seq := func(yield func(rune) bool) {
yield('C')
yield('A')
yield('T')
}fmt.Println(gloop.ToString(seq))
}
``````
CAT
```## Parallelizers
### Parallelize
`Parallelize` runs a function on each value from given a slice of values on separate goroutines.
```go
package mainimport (
"fmt"
"time""github.com/alvii147/gloop"
)func printlnWithDelay(s string) {
time.Sleep(time.Second)
fmt.Println(s)
}func main() {
values := []string{"CAT", "DOG", "MOUSE"}
timeElaped := time.Now()
gloop.Parallelize(gloop.Slice(values), printlnWithDelay)
fmt.Println("Time Elapsed", time.Since(timeElaped))
}
``````
MOUSE
DOG
CAT
Time Elapsed 1.001531166s
````WithParallelizeContext` can be used to pass in a context. If the context is cancelled, no more goroutines are started.
```go
package mainimport (
"context"
"fmt"
"time""github.com/alvii147/gloop"
)func printlnWithDelay(s string) {
time.Sleep(time.Second)
fmt.Println(s)
}func main() {
values := []string{"CAT", "DOG", "MOUSE"}
timeElaped := time.Now()ctx, cancel := context.WithCancel(context.Background())
cancel()gloop.Parallelize(gloop.Slice(values), printlnWithDelay, gloop.WithParallelizeContext(ctx))
fmt.Println("Time Elapsed", time.Since(timeElaped))
}
``````
Time Elapsed 50.5µs
````WithParallelizeMaxThreads` can be used to configure the maximum number of concurrent goroutines.
```go
package mainimport (
"fmt"
"time""github.com/alvii147/gloop"
)func printlnWithDelay(s string) {
time.Sleep(time.Second)
fmt.Println(s)
}func main() {
values := []string{"CAT", "DOG", "MOUSE"}
timeElaped := time.Now()
gloop.Parallelize(
gloop.Slice(values),
func(s string) {
printlnWithDelay(s)
fmt.Println(time.Since(timeElaped))
},
gloop.WithParallelizeMaxThreads(2),
)
fmt.Println("Time Elapsed", time.Since(timeElaped))
}
``````
CAT
DOG
1.001607s
1.001604792s
MOUSE
2.0021425s
Time Elapsed 2.002274583s
```