Skip to content

Latest commit

 

History

History
1007 lines (707 loc) · 19.5 KB

stream.md

File metadata and controls

1007 lines (707 loc) · 19.5 KB

Stream

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 feature is very limited.

Source:

Usage:

import (
    "github.com/duke-git/lancet/v2/stream"
)

Index

Documentation

Of

Creates a stream whose elements are the specified values.

Signature:

func Of[T any](elems ...T) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.Of(1, 2, 3)

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3]
}

FromSlice

Creates a stream from slice.

Signature:

func FromSlice[T any](source []T) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.FromSlice([]int{1, 2, 3})

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3]
}

FromChannel

Creates a stream from channel.

Signature:

func FromChannel[T any](source <-chan T) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    ch := make(chan int)
    go func() {
        for i := 1; i < 4; i++ {
            ch <- i
        }
        close(ch)
    }()

    s := stream.FromChannel(ch)

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3]
}

FromRange

Creates a number stream from start to end. both start and end are included. [start, end]

Signature:

func FromRange[T constraints.Integer | constraints.Float](start, end, step T) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.FromRange(1, 5, 1)

    data := s.ToSlice()
    fmt.Println(data)

    // Output:
    // [1 2 3 4 5]
}

Generate

Creates a stream where each element is generated by the provided generater function.

Signature:

func Generate[T any](generator func() func() (item T, ok bool)) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    n := 0
    max := 4

    generator := func() func() (int, bool) {
        return func() (int, bool) {
            n++
            return n, n < max
        }
    }

    s := stream.Generate(generator)

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3]
}

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.

Signature:

func Concat[T any](a, b stream[T]) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s1 := stream.FromSlice([]int{1, 2, 3})
    s2 := stream.FromSlice([]int{4, 5, 6})

    s := Concat(s1, s2)

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3 4 5 6]
}

Distinct

Creates returns a stream that removes the duplicated items. Support chainable operation

Signature:

func (s stream[T]) Distinct() stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 2, 3, 3, 3})
    distinct := original.Distinct()

    data1 := original.ToSlice()
    data2 := distinct.ToSlice()

    fmt.Println(data1)
    fmt.Println(data2)

    // Output:
    // [1 2 2 3 3 3]
    // [1 2 3]
}

Filter

Returns a stream consisting of the elements of this stream that match the given predicate. Support chainable operation

Signature:

func (s stream[T]) Filter(predicate func(item T) bool) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3, 4, 5})

    isEven := func(n int) bool {
        return n%2 == 0
    }

    even := original.Filter(isEven)

    fmt.Println(even.ToSlice())

    // Output:
    // [2 4]
}

Map

Returns a stream consisting of the elements of this stream that apply the given function to elements of stream. Support chainable operation

Signature:

func (s stream[T]) Map(mapper func(item T) T) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    addOne := func(n int) int {
        return n + 1
    }

    increament := original.Map(addOne)

    fmt.Println(increament.ToSlice())

    // Output:
    // [2 3 4]
}

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. Support chainable operation

Signature:

func (s stream[T]) Peek(consumer func(item T)) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    data := []string{}
    peekStream := original.Peek(func(n int) {
        data = append(data, fmt.Sprint("value", n))
    })

    fmt.Println(original.ToSlice())
    fmt.Println(peekStream.ToSlice())
    fmt.Println(data)

    // Output:
    // [1 2 3]
    // [1 2 3]
    // [value1 value2 value3]
}

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. Support chainable operation

Signature:

func (s stream[T]) Skip(n int) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3, 4})

    s1 := original.Skip(-1)
    s2 := original.Skip(0)
    s3 := original.Skip(1)
    s4 := original.Skip(5)

    fmt.Println(s1.ToSlice())
    fmt.Println(s2.ToSlice())
    fmt.Println(s3.ToSlice())
    fmt.Println(s4.ToSlice())

    // Output:
    // [1 2 3 4]
    // [1 2 3 4]
    // [2 3 4]
    // []
}

Limit

Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. Support chainable operation

Signature:

func (s stream[T]) Limit(maxSize int) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3, 4})

    s1 := original.Limit(-1)
    s2 := original.Limit(0)
    s3 := original.Limit(1)
    s4 := original.Limit(5)

    fmt.Println(s1.ToSlice())
    fmt.Println(s2.ToSlice())
    fmt.Println(s3.ToSlice())
    fmt.Println(s4.ToSlice())

    // Output:
    // []
    // []
    // [1]
    // [1 2 3 4]
}

Reverse

Returns a stream whose elements are reverse order of given stream. Support chainable operation

Signature:

func (s stream[T]) Reverse() stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    reverse := original.Reverse()

    fmt.Println(reverse.ToSlice())

    // Output:
    // [3 2 1]
}

Range

Returns a stream whose elements are in the range from start(included) to end(excluded) original stream.Support chainable operation

Signature:

func (s stream[T]) Range(start, end int) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    s1 := original.Range(0, 0)
    s2 := original.Range(0, 1)
    s3 := original.Range(0, 3)
    s4 := original.Range(1, 2)

    fmt.Println(s1.ToSlice())
    fmt.Println(s2.ToSlice())
    fmt.Println(s3.ToSlice())
    fmt.Println(s4.ToSlice())

    // Output:
    // []
    // [1]
    // [1 2 3]
    // [2]
}

Sorted

Returns a stream consisting of the elements of this stream, sorted according to the provided less function.Support chainable operation

Signature:

func (s stream[T]) Sorted(less func(a, b T) bool) stream[T]

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{4, 2, 1, 3})

    sorted := original.Sorted(func(a, b int) bool { return a < b })

    fmt.Println(original.ToSlice())
    fmt.Println(sorted.ToSlice())

    // Output:
    // [4 2 1 3]
    // [1 2 3 4]
}

ForEach

Performs an action for each element of this stream.

Signature:

func (s stream[T]) ForEach(action func(item T))

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result := 0
    original.ForEach(func(item int) {
        result += item
    })

    fmt.Println(result)

    // Output:
    // 6
}

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.

Signature:

func (s stream[T]) Reduce(initial T, accumulator func(a, b T) T) T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result := original.Reduce(0, func(a, b int) int {
        return a + b
    })

    fmt.Println(result)

    // Output:
    // 6
}

FindFirst

Returns the first element of this stream and true, or zero value and false if the stream is empty.

Signature:

func (s stream[T]) FindFirst() (T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result, ok := original.FindFirst()

    fmt.Println(result)
    fmt.Println(ok)

    // Output:
    // 1
    // true
}

FindLast

Returns the last element of this stream and true, or zero value and false if the stream is empty.

Signature:

func (s stream[T]) FindLast() (T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{3, 2, 1})

    result, ok := original.FindLast()

    fmt.Println(result)
    fmt.Println(ok)

    // Output:
    // 1
    // true
}

Max

Returns the maximum element of this stream according to the provided less function. less fuction: a > b

Signature:

func (s stream[T]) Max(less func(a, b T) bool) (T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{4, 2, 1, 3})

    max, ok := original.Max(func(a, b int) bool { return a > b })

    fmt.Println(max)
    fmt.Println(ok)

    // Output:
    // 4
    // true
}

Min

Returns the minimum element of this stream according to the provided less function. less fuction: a < b

Signature:

func (s stream[T]) Min(less func(a, b T) bool) (T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{4, 2, 1, 3})

    min, ok := original.Min(func(a, b int) bool { return a < b })

    fmt.Println(min)
    fmt.Println(ok)

    // Output:
    // 1
    // true
}

AllMatch

Returns whether all elements of this stream match the provided predicate.

Signature:

func (s stream[T]) AllMatch(predicate func(item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result1 := original.AllMatch(func(item int) bool {
        return item > 0
    })

    result2 := original.AllMatch(func(item int) bool {
        return item > 1
    })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

AnyMatch

Returns whether any elements of this stream match the provided predicate.

Signature:

func (s stream[T]) AnyMatch(predicate func(item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result1 := original.AnyMatch(func(item int) bool {
        return item > 1
    })

    result2 := original.AnyMatch(func(item int) bool {
        return item > 3
    })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

NoneMatch

Returns whether no elements of this stream match the provided predicate.

Signature:

func (s stream[T]) NoneMatch(predicate func(item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    original := stream.FromSlice([]int{1, 2, 3})

    result1 := original.NoneMatch(func(item int) bool {
        return item > 3
    })

    result2 := original.NoneMatch(func(item int) bool {
        return item > 1
    })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

Count

Returns the count of elements in the stream.

Signature:

func (s stream[T]) Count() int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s1 := stream.FromSlice([]int{1, 2, 3})
    s2 := stream.FromSlice([]int{})

    fmt.Println(s1.Count())
    fmt.Println(s2.Count())

    // Output:
    // 3
    // 0
}

ToSlice

Returns the elements in the stream.

Signature:

func (s stream[T]) ToSlice() []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.Of(1, 2, 3)

    data := s.ToSlice()

    fmt.Println(data)

    // Output:
    // [1 2 3]
}

IndexOf

Returns the index of the first occurrence of the specified element in this stream, or -1 if this stream does not contain the element.

Signature:

func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.FromSlice([]int{1, 2, 3, 2})

    result1 := s.IndexOf(0, func(a, b int) bool { return a == b })
    result2 := s.IndexOf(2, func(a, b int) bool { return a == b })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // -1
    // 1
}

LastIndexOf

Returns the index of the last occurrence of the specified element in this stream, or -1 if this stream does not contain the element.

Signature:

func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/stream"
)

func main() {
    s := stream.FromSlice([]int{1, 2, 3, 2})

    result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b })
    result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // -1
    // 3
}