1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-12 00:32:27 +08:00

test: add example for stream package

This commit is contained in:
dudaodong
2023-04-05 18:52:27 +08:00
parent 6e7300bbbf
commit 5b9b4c4344
3 changed files with 422 additions and 10 deletions

View File

@@ -1,9 +1,8 @@
// Copyright 2023 dudaodong@gmail.com. All rights resulterved.
// Use of this source code is governed by MIT license
// Package stream implements a sequence of elements supporting sequential and parallel aggregate operations.
// this package is an experiment to explore if stream in go can work as the way java does. it's complete, but not
// powerful like other libs
// Package stream implements a sequence of elements supporting sequential and operations.
// this package is an experiment to explore if stream in go can work as the way java does. it's function is very limited.
package stream
import (
@@ -53,12 +52,13 @@ type stream[T any] struct {
}
// Of creates a stream stream whose elements are the specified values.
// Play: https://go.dev/play/p/jI6_iZZuVFE
func Of[T any](elems ...T) stream[T] {
return FromSlice(elems)
}
// Generate stream where each element is generated by the provided generater function
// generater function: func() func() (item T, ok bool) {}
// Play: https://go.dev/play/p/rkOWL1yA3j9
func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
source := make([]T, 0)
@@ -75,11 +75,13 @@ func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
}
// FromSlice creates stream from slice.
// Play: https://go.dev/play/p/wywTO0XZtI4
func FromSlice[T any](source []T) stream[T] {
return stream[T]{source: source}
}
// FromChannel creates stream from channel.
// Play: https://go.dev/play/p/9TZYugGMhXZ
func FromChannel[T any](source <-chan T) stream[T] {
s := make([]T, 0)
@@ -91,6 +93,7 @@ func FromChannel[T any](source <-chan T) stream[T] {
}
// FromRange creates a number stream from start to end. both start and end are included. [start, end]
// Play: https://go.dev/play/p/9Ex1-zcg-B-
func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T] {
if end < start {
panic("stream.FromRange: param start should be before param end")
@@ -109,6 +112,7 @@ func FromRange[T constraints.Integer | constraints.Float](start, end, step T) st
}
// Concat creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
// Play: https://go.dev/play/p/HM4OlYk_OUC
func Concat[T any](a, b stream[T]) stream[T] {
source := make([]T, 0)
@@ -119,6 +123,7 @@ func Concat[T any](a, b stream[T]) stream[T] {
}
// Distinct returns a stream that removes the duplicated items.
// Play: https://go.dev/play/p/eGkOSrm64cB
func (s stream[T]) Distinct() stream[T] {
source := make([]T, 0)
@@ -147,6 +152,7 @@ func hashKey(data any) string {
}
// Filter returns a stream consisting of the elements of this stream that match the given predicate.
// Play: https://go.dev/play/p/MFlSANo-buc
func (s stream[T]) Filter(predicate func(item T) bool) stream[T] {
source := make([]T, 0)
@@ -160,6 +166,7 @@ func (s stream[T]) Filter(predicate func(item T) bool) stream[T] {
}
// Map returns a stream consisting of the elements of this stream that apply the given function to elements of stream.
// Play: https://go.dev/play/p/OtNQUImdYko
func (s stream[T]) Map(mapper func(item T) T) stream[T] {
source := make([]T, s.Count())
@@ -171,6 +178,7 @@ func (s stream[T]) Map(mapper func(item T) T) stream[T] {
}
// Peek returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
// Play: https://go.dev/play/p/u1VNzHs6cb2
func (s stream[T]) Peek(consumer func(item T)) stream[T] {
for _, v := range s.source {
consumer(v)
@@ -181,6 +189,7 @@ func (s stream[T]) Peek(consumer func(item T)) stream[T] {
// Skip returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.
// If this stream contains fewer than n elements then an empty stream will be returned.
// Play: https://go.dev/play/p/fNdHbqjahum
func (s stream[T]) Skip(n int) stream[T] {
if n <= 0 {
return s
@@ -201,6 +210,7 @@ func (s stream[T]) Skip(n int) stream[T] {
}
// Limit returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
// Play: https://go.dev/play/p/qsO4aniDcGf
func (s stream[T]) Limit(maxSize int) stream[T] {
if s.source == nil {
return s
@@ -220,6 +230,7 @@ func (s stream[T]) Limit(maxSize int) stream[T] {
}
// AllMatch returns whether all elements of this stream match the provided predicate.
// Play: https://go.dev/play/p/V5TBpVRs-Cx
func (s stream[T]) AllMatch(predicate func(item T) bool) bool {
for _, v := range s.source {
if !predicate(v) {
@@ -231,6 +242,7 @@ func (s stream[T]) AllMatch(predicate func(item T) bool) bool {
}
// AnyMatch returns whether any elements of this stream match the provided predicate.
// Play: https://go.dev/play/p/PTCnWn4OxSn
func (s stream[T]) AnyMatch(predicate func(item T) bool) bool {
for _, v := range s.source {
if predicate(v) {
@@ -242,11 +254,13 @@ func (s stream[T]) AnyMatch(predicate func(item T) bool) bool {
}
// NoneMatch returns whether no elements of this stream match the provided predicate.
// Play: https://go.dev/play/p/iWS64pL1oo3
func (s stream[T]) NoneMatch(predicate func(item T) bool) bool {
return !s.AnyMatch(predicate)
}
// ForEach performs an action for each element of this stream.
// Play: https://go.dev/play/p/Dsm0fPqcidk
func (s stream[T]) ForEach(action func(item T)) {
for _, v := range s.source {
action(v)
@@ -254,20 +268,23 @@ func (s stream[T]) ForEach(action func(item T)) {
}
// Reduce performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
func (s stream[T]) Reduce(init T, accumulator func(a, b T) T) T {
// Play: https://go.dev/play/p/g-xkHiuIpTi
func (s stream[T]) Reduce(initial T, accumulator func(a, b T) T) T {
for _, v := range s.source {
init = accumulator(init, v)
initial = accumulator(initial, v)
}
return init
return initial
}
// Count returns the count of elements in the stream.
// Play: https://go.dev/play/p/r3koY6y_Xo-
func (s stream[T]) Count() int {
return len(s.source)
}
// FindFirst returns the first element of this stream and true, or zero value and false if the stream is empty.
// Play: https://go.dev/play/p/9xEf0-6C1e3
func (s stream[T]) FindFirst() (T, bool) {
var result T
@@ -279,6 +296,7 @@ func (s stream[T]) FindFirst() (T, bool) {
}
// Reverse returns a stream whose elements are reverse order of given stream.
// Play: https://go.dev/play/p/A8_zkJnLHm4
func (s stream[T]) Reverse() stream[T] {
l := len(s.source)
source := make([]T, l)
@@ -290,6 +308,7 @@ func (s stream[T]) Reverse() stream[T] {
}
// Range returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
// Play: https://go.dev/play/p/indZY5V2f4j
func (s stream[T]) Range(start, end int) stream[T] {
if start < 0 {
start = 0
@@ -315,6 +334,7 @@ func (s stream[T]) Range(start, end int) stream[T] {
}
// Sorted returns a stream consisting of the elements of this stream, sorted according to the provided less function.
// Play: https://go.dev/play/p/XXtng5uonFj
func (s stream[T]) Sorted(less func(a, b T) bool) stream[T] {
source := []T{}
source = append(source, s.source...)
@@ -326,6 +346,7 @@ func (s stream[T]) Sorted(less func(a, b T) bool) stream[T] {
// Max returns the maximum element of this stream according to the provided less function.
// less: a > b
// Play: https://go.dev/play/p/fm-1KOPtGzn
func (s stream[T]) Max(less func(a, b T) bool) (T, bool) {
var max T
@@ -343,6 +364,7 @@ func (s stream[T]) Max(less func(a, b T) bool) (T, bool) {
// Min returns the minimum element of this stream according to the provided less function.
// less: a < b
// Play: https://go.dev/play/p/vZfIDgGNRe_0
func (s stream[T]) Min(less func(a, b T) bool) (T, bool) {
var min T
@@ -360,6 +382,7 @@ func (s stream[T]) Min(less func(a, b T) bool) (T, bool) {
}
// ToSlice return the elements in the stream.
// Play: https://go.dev/play/p/jI6_iZZuVFE
func (s stream[T]) ToSlice() []T {
return s.source
}