1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

Compare commits

...

3 Commits

Author SHA1 Message Date
dudaodong
6bba44dc50 feat: add Concat for stream 2023-02-07 10:47:28 +08:00
dudaodong
422022c74d feat: add Range for stream 2023-02-07 10:36:07 +08:00
dudaodong
87fcf97e2d feat: add FindFirst, Reverse for stream 2023-02-07 10:24:19 +08:00
2 changed files with 117 additions and 4 deletions

View File

@@ -43,7 +43,7 @@ import (
// // part of methods custom extension
// Reverse() StreamI[T]
// Range(start, end int64) StreamI[T]
// Range(start, end int) StreamI[T]
// Concat(streams ...StreamI[T]) StreamI[T]
// }
@@ -72,12 +72,12 @@ func Generate[T any](generator func() func() (item T, ok bool)) stream[T] {
return FromSlice(source)
}
// FromSlice create stream from slice.
// FromSlice creates stream from slice.
func FromSlice[T any](source []T) stream[T] {
return stream[T]{source: source}
}
// FromChannel create stream from channel.
// FromChannel creates stream from channel.
func FromChannel[T any](source <-chan T) stream[T] {
s := make([]T, 0)
@@ -88,7 +88,7 @@ func FromChannel[T any](source <-chan T) stream[T] {
return FromSlice(s)
}
// FromRange create a number stream from start to end. both start and end are included. [start, end]
// FromRange creates a number stream from start to end. both start and end are included. [start, end]
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")
@@ -106,6 +106,16 @@ func FromRange[T constraints.Integer | constraints.Float](start, end, step T) st
return FromSlice(source)
}
// 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.
func Concat[T any](a, b stream[T]) stream[T] {
source := make([]T, 0)
source = append(source, a.source...)
source = append(source, b.source...)
return FromSlice(source)
}
// Distinct returns a stream that removes the duplicated items.
func (s stream[T]) Distinct() stream[T] {
source := make([]T, 0)
@@ -255,6 +265,53 @@ 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.
func (s stream[T]) FindFirst() (T, bool) {
var result T
if s.source == nil || len(s.source) == 0 {
return result, false
}
return s.source[0], true
}
// Reverse returns a stream whose elements are reverse order of given stream.
func (s stream[T]) Reverse() stream[T] {
l := len(s.source)
source := make([]T, l)
for i := 0; i < l; i++ {
source[i] = s.source[l-1-i]
}
return FromSlice(source)
}
// Range returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
func (s stream[T]) Range(start, end int) stream[T] {
if start < 0 {
start = 0
}
if end < 0 {
end = 0
}
if start >= end {
return FromSlice([]T{})
}
source := make([]T, 0)
if end > len(s.source) {
end = len(s.source)
}
for i := start; i < end; i++ {
source = append(source, s.source[i])
}
return FromSlice(source)
}
// ToSlice return the elements in the stream.
func (s stream[T]) ToSlice() []T {
return s.source

View File

@@ -247,3 +247,59 @@ func TestStream_Reduce(t *testing.T) {
assert.Equal(6, result)
}
func TestStream_FindFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_FindFirst")
stream := FromSlice([]int{1, 2, 3})
result, ok := stream.FindFirst()
assert.Equal(1, result)
assert.Equal(true, ok)
}
func TestStream_Reverse(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Reverse")
s := FromSlice([]int{1, 2, 3})
rs := s.Reverse()
assert.Equal([]int{3, 2, 1}, rs.ToSlice())
}
func TestStream_Range(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Range")
s := FromSlice([]int{1, 2, 3})
s1 := s.Range(-1, 0)
assert.Equal([]int{}, s1.ToSlice())
s2 := s.Range(0, -1)
assert.Equal([]int{}, s2.ToSlice())
s3 := s.Range(0, 0)
assert.Equal([]int{}, s3.ToSlice())
s4 := s.Range(1, 1)
assert.Equal([]int{}, s4.ToSlice())
s5 := s.Range(0, 1)
assert.Equal([]int{1}, s5.ToSlice())
s6 := s.Range(0, 4)
assert.Equal([]int{1, 2, 3}, s6.ToSlice())
}
func TestStream_Concat(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_Concat")
s1 := FromSlice([]int{1, 2, 3})
s2 := FromSlice([]int{4, 5, 6})
s := Concat(s1, s2)
assert.Equal([]int{1, 2, 3, 4, 5, 6}, s.ToSlice())
}