Skip to content

Commit

Permalink
range-over-func
Browse files Browse the repository at this point in the history
  • Loading branch information
youthlin.chen committed Feb 8, 2024
1 parent 569337c commit cefbf40
Show file tree
Hide file tree
Showing 10 changed files with 907 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go.work
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"go.toolsEnvVars": {
"GOEXPERIMENT": "rangefunc"
}
}
141 changes: 141 additions & 0 deletions v2/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package stream_test

import (
"fmt"
"iter"
"strings"

"github.com/youthlin/stream/v2"
"github.com/youthlin/stream/v2/types"
)

func ExampleOf() {
fmt.Printf("Of(): %v\n", stream.Of[int]().Count())
fmt.Printf("Of(1): %v\n", stream.Of(1).Count())
var s = []int{1, 2, 3, 4}
fmt.Printf("Of(...): %v\n", stream.Of(s...).Count())
stream.Of(s...).Skip(1).Limit(2).ForEach(func(i int) {
fmt.Printf("%d,", i)
})
// Output:
// Of(): 0
// Of(1): 1
// Of(...): 4
// 2,3,
}

func ExampleCountFrom() {
s := stream.CountFrom(0).Limit(4).Peek(func(i int) {
fmt.Printf("%d;", i)
}).Skip(2).Collect()
fmt.Println(s)
// Output:
// 0;1;2;3;[2 3]
}

func ExampleRange() {
fmt.Println(stream.Range(0, 10).Limit(9).Count())
stream.RangeStep(5, 0, -1).Limit(4).ForEach(func(i int) {
fmt.Printf("%d,", i)
})
// Output:
// 9
// 5,4,3,2,
}

func ExampleRepeat() {
fmt.Println(strings.Join(stream.Repeat("a").Limit(5).Collect(), ""))
// Output:
// aaaaa
}

func fib() types.Supplier[int] {
a := -1
b := 1
return func() int {
n := a + b
a = b
b = n
return n
}
}
func ExampleGenerate() {
stream.Generate(fib()).Limit(10).ForEach(func(i int) {
fmt.Printf("%d,", i)
})
// Output:
// 0,1,1,2,3,5,8,13,21,34,
}

func ExampleStream() {
stream.Generate(fib()).Filter(func(i int) bool {
if i%2 == 0 {
fmt.Printf("[%dok]", i)
return true
} else {
fmt.Printf("[%dno]", i)
return false
}
}).Peek(func(i int) {
fmt.Printf("<%d>", i)
}).Map(func(i int) int {
return i * 10
}).Limit(3).ForEach(func(i int) {
fmt.Printf("got=%d,", i)
})
// Output:
// [0ok]<0>got=0,[1no][1no][2ok]<2>got=20,[3no][5no][8ok]<8>got=80,
}

func ExampleStreamFlatMap() {
var i int64 = 0
stream.Of("a", "c", "b").FlatMap(func(s string) iter.Seq[string] {
i++
return stream.Repeat(s).Limit(i).Seq()
}).Sorted(func(s1, s2 string) int {
return strings.Compare(s1, s2)
}).ForEach(func(s string) {
fmt.Printf("%v,", s)
})
// Output:
// a,b,b,b,c,c,
}

func ExampleDistict() {
s := stream.Repeat(1).Limit(10).Distinct(func(i int) int {
return i
}).Collect()
fmt.Println(s)
// Output:
// [1]
}

func ExampleMatch() {
fmt.Println(stream.Repeat(1).Limit(10).AllMatch(func(i int) bool {
return i == 1
}))
fmt.Println(stream.Range(1, 10).Limit(10).AnyMatch(func(i int) bool {
return i == 5
}))
fmt.Println(stream.Repeat(1).Limit(10).NoneMatch(func(i int) bool {
return i > 0
}))
// Output:
// true
// true
// false
}

func ExampleReduce() {
fmt.Println(stream.Range(1, 101).Reduce(func(i1, i2 int) int {
return i1 + i2
}).Value())
fmt.Println(stream.Range(1, 2).ReduceFrom(100, func(i1, i2 int) int {
return i1 + i2
}))
fmt.Println(stream.Of[int]().FindFirst().IsAbsent())
// Output:
// 5050
// 101
// true
}
91 changes: 91 additions & 0 deletions v2/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package stream

import (
"iter"

"github.com/youthlin/stream/v2/types"
)

// Of build a Seq by input elements.
// 使用输入的任意个元素创建一个序列
func Of[T any](elements ...T) Seq[T] {
return func(yield func(T) bool) {
for _, e := range elements {
if !yield(e) {
return
}
}
}
}

// OfSeq convert from iter.Seq.
// 类型转换, 从 iter.Seq 转为 Seq.
func OfSeq[T any](s iter.Seq[T]) Seq[T] {
return Seq[T](s)
}

// CountFrom build a Seq count infinite from the input number.
// 构造一个从指定数字开始计数的序列
func CountFrom[T types.Int](from T) Seq[T] {
return func(yield func(T) bool) {
for i := from; ; i++ {
if !yield(i) {
return
}
}
}
}

// Range build a Seq count from fromInclude to toExclude.
// 构造一个左闭右开的区间序列
func Range[T types.Int](fromInclude, toExclude T) Seq[T] {
return RangeStep(fromInclude, toExclude, 1)
}

// RangeStep build a Seq count from fromInclude to toExclude.
// step may negetive.
// 按指定步进大小构造一个左闭右开的序列, 步进大小可以是负数
func RangeStep[T types.Int](fromInclude, toExclude, step T) Seq[T] {
return func(yield func(T) bool) {
if step >= 0 {
for i := fromInclude; i < toExclude; i += step {
if !yield(i) {
return
}
}
} else {
for i := fromInclude; i > toExclude; i += step {
if !yield(i) {
return
}
}
}

}
}

// Repeat create an infinite Seq,
// which all elements is same as the input element.
// 使用输入的单个元素创建一个无限序列
func Repeat[T any](e T) Seq[T] {
return func(yield func(T) bool) {
for {
if !yield(e) {
return
}
}
}
}

// Generate build a Seq,
// which each element is generate by the Supplier.
// 通过生成器生成一个序列
func Generate[T any](get types.Supplier[T]) Seq[T] {
return func(yield func(T) bool) {
for {
if !yield(get()) {
return
}
}
}
}
3 changes: 3 additions & 0 deletions v2/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/youthlin/stream/v2

go 1.22.0
Loading

0 comments on commit cefbf40

Please sign in to comment.