v1.0
This commit is contained in:
parent
37f72029d9
commit
feddf28725
|
@ -0,0 +1,52 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/go-func/stream"
|
||||||
|
"github.com/go-func/stream/collectors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := make([]interface{}, 100)
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
list[i] = i * 2
|
||||||
|
}
|
||||||
|
tmp := NewParallelStream(list).Filter(func(item interface{}) bool {
|
||||||
|
if item.(int) < 100 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}).Map(func(item interface{}) interface{} {
|
||||||
|
value := item.(int)
|
||||||
|
value /= 2
|
||||||
|
return value
|
||||||
|
}).Collect(&collectors.GroupingBy{Classifier: func(item interface{}) interface{} {
|
||||||
|
return item.(int)%2 == 0
|
||||||
|
}, DownStream: &collectors.PartitioningBy{Predicate: func(item interface{}) bool {
|
||||||
|
return item.(int)%3 == 0
|
||||||
|
}, DownStream: &collectors.SummarizingFloat64{Mapper: func(item interface{}) float64 {
|
||||||
|
return float64(item.(int))
|
||||||
|
}}}})
|
||||||
|
/*
|
||||||
|
.Collect(&collectors.PartitioningBy{Predicate: func(item interface{}) bool {
|
||||||
|
return item.(int)%3 == 0
|
||||||
|
}})
|
||||||
|
.Collect(&collectors.GroupingBy{Classifier: func(item interface{}) interface{} {
|
||||||
|
return item.(int)%3 == 0
|
||||||
|
}})
|
||||||
|
.Collect(&collectors.Joining{Prefix: "[", Suffix: "]", Delimiter: ","})
|
||||||
|
.Collect(&collectors.Counting{})
|
||||||
|
.Collect(&collectors.AveragingFloat64{Mapper: func(item interface{}) float64 {
|
||||||
|
return float64(item.(int))
|
||||||
|
}})
|
||||||
|
.Collect(&collectors.ToMap{KeyMapper: func(item interface{}) interface{} {
|
||||||
|
return item.(int) * 2
|
||||||
|
}, ValueMapper: func(item interface{}) interface{} {
|
||||||
|
return item
|
||||||
|
}})
|
||||||
|
.Collect(&collectors.SummarizingFloat64{Mapper: func(item interface{}) float64 {
|
||||||
|
return float64(item.(int))
|
||||||
|
}})
|
||||||
|
*/
|
||||||
|
fmt.Println(tmp)
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package stream
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
// Collector 收集器接口,对于所有的并发流,定义打包行为
|
||||||
|
type Collector interface {
|
||||||
|
Supplier() func() interface{}
|
||||||
|
Accumulator() func(interface{}, interface{}) interface{}
|
||||||
|
Combiner() func(interface{}, interface{}) interface{}
|
||||||
|
Finisher() func(interface{}) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect 收集器,对于所有的并发流,打包
|
||||||
|
func (s *Stream) Collect(collector Collector) interface{} {
|
||||||
|
identity := collector.Supplier()()
|
||||||
|
if s.isParallel {
|
||||||
|
count := runtime.NumCPU()
|
||||||
|
ch1 := make(chan interface{}, count)
|
||||||
|
ch2 := make(chan interface{})
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
go func() {
|
||||||
|
result := collector.Supplier()()
|
||||||
|
for true {
|
||||||
|
if value, ok := <-ch1; !ok {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
result = collector.Accumulator()(result, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ch2 <- result
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for _, v := range s.list {
|
||||||
|
ch1 <- v
|
||||||
|
}
|
||||||
|
close(ch1)
|
||||||
|
}()
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
tmp := <-ch2
|
||||||
|
identity = collector.Combiner()(identity, tmp)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v := range s.list {
|
||||||
|
identity = collector.Accumulator()(identity, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
identity = collector.Finisher()(identity)
|
||||||
|
return identity
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
// ToMap 按照指定的规则组装为Map
|
||||||
|
type ToMap struct {
|
||||||
|
KeyMapper func(interface{}) interface{}
|
||||||
|
ValueMapper func(interface{}) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (tm *ToMap) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return make(map[interface{}]interface{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (tm *ToMap) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
ret := identity.(map[interface{}]interface{})
|
||||||
|
k := tm.KeyMapper(element)
|
||||||
|
v := tm.ValueMapper(element)
|
||||||
|
ret[k] = v
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (tm *ToMap) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
mapA := a.(map[interface{}]interface{})
|
||||||
|
mapB := b.(map[interface{}]interface{})
|
||||||
|
for k, v := range mapB {
|
||||||
|
if _, ok := mapA[k]; !ok {
|
||||||
|
mapA[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mapA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (tm *ToMap) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
return identity
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
// AveragingFloat64 统计结果集平均值
|
||||||
|
type AveragingFloat64 struct {
|
||||||
|
Mapper func(interface{}) float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type aveMidResult struct {
|
||||||
|
Sum float64
|
||||||
|
Count int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (ave *AveragingFloat64) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return aveMidResult{Sum: 0, Count: 0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (ave *AveragingFloat64) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
mid := identity.(aveMidResult)
|
||||||
|
mid.Count++
|
||||||
|
mid.Sum += ave.Mapper(element)
|
||||||
|
return mid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (ave *AveragingFloat64) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
midA := a.(aveMidResult)
|
||||||
|
midB := b.(aveMidResult)
|
||||||
|
midA.Sum += midB.Sum
|
||||||
|
midA.Count += midB.Count
|
||||||
|
return midA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (ave *AveragingFloat64) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
mid := identity.(aveMidResult)
|
||||||
|
return mid.Sum / float64(mid.Count)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
// Counting 统计结果集数量
|
||||||
|
type Counting struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (c *Counting) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return int(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (c *Counting) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
return identity.(int) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (c *Counting) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
return a.(int) + b.(int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (c *Counting) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
return identity
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
import . "github.com/go-func/stream"
|
||||||
|
|
||||||
|
// GroupingBy 按照指定的规则分组
|
||||||
|
type GroupingBy struct {
|
||||||
|
Classifier func(interface{}) interface{}
|
||||||
|
DownStream Collector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (g *GroupingBy) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return make(map[interface{}][]interface{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (g *GroupingBy) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
ret := identity.(map[interface{}][]interface{})
|
||||||
|
k := g.Classifier(element)
|
||||||
|
if value, ok := ret[k]; ok {
|
||||||
|
ret[k] = append(value, element)
|
||||||
|
} else {
|
||||||
|
list := make([]interface{}, 1)
|
||||||
|
list[0] = element
|
||||||
|
ret[k] = list
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (g *GroupingBy) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
mapA := a.(map[interface{}][]interface{})
|
||||||
|
mapB := b.(map[interface{}][]interface{})
|
||||||
|
for k, v := range mapB {
|
||||||
|
if value, ok := mapA[k]; ok {
|
||||||
|
mapA[k] = append(value, v...)
|
||||||
|
} else {
|
||||||
|
mapA[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mapA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (g *GroupingBy) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
if g.DownStream != nil {
|
||||||
|
result := identity.(map[interface{}][]interface{})
|
||||||
|
downStreamResult := make(map[interface{}]interface{})
|
||||||
|
for k, v := range result {
|
||||||
|
downStreamResult[k] = NewStream(v).Collect(g.DownStream)
|
||||||
|
}
|
||||||
|
return downStreamResult
|
||||||
|
}
|
||||||
|
return identity
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Joining 按照指定的连接成字符串
|
||||||
|
type Joining struct {
|
||||||
|
Delimiter string
|
||||||
|
Suffix string
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (j *Joining) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (j *Joining) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
buffer := identity.(bytes.Buffer)
|
||||||
|
switch element.(type) {
|
||||||
|
case string:
|
||||||
|
buffer.WriteString(element.(string))
|
||||||
|
case int:
|
||||||
|
buffer.WriteString(strconv.Itoa(element.(int)))
|
||||||
|
default:
|
||||||
|
str2 := fmt.Sprintf("%v", element)
|
||||||
|
buffer.WriteString(str2)
|
||||||
|
}
|
||||||
|
buffer.WriteString(j.Delimiter)
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (j *Joining) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
bufferA := a.(bytes.Buffer)
|
||||||
|
bufferB := b.(bytes.Buffer)
|
||||||
|
bufferA.WriteString(bufferB.String())
|
||||||
|
return bufferA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (j *Joining) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
buffer := identity.(bytes.Buffer)
|
||||||
|
str := buffer.String()
|
||||||
|
if len(str) > 0 {
|
||||||
|
str = str[:len(str)-len(j.Delimiter)]
|
||||||
|
}
|
||||||
|
ret := j.Prefix + str + j.Suffix
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
import . "github.com/go-func/stream"
|
||||||
|
|
||||||
|
// PartitioningBy 按照指定的分区
|
||||||
|
type PartitioningBy struct {
|
||||||
|
Predicate func(interface{}) bool
|
||||||
|
DownStream Collector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (p *PartitioningBy) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return make(map[bool][]interface{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (p *PartitioningBy) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
ret := identity.(map[bool][]interface{})
|
||||||
|
k := p.Predicate(element)
|
||||||
|
if value, ok := ret[k]; ok {
|
||||||
|
ret[k] = append(value, element)
|
||||||
|
} else {
|
||||||
|
list := make([]interface{}, 1)
|
||||||
|
list[0] = element
|
||||||
|
ret[k] = list
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (p *PartitioningBy) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
mapA := a.(map[bool][]interface{})
|
||||||
|
mapB := b.(map[bool][]interface{})
|
||||||
|
for k, v := range mapB {
|
||||||
|
if value, ok := mapA[k]; ok {
|
||||||
|
mapA[k] = append(value, v...)
|
||||||
|
} else {
|
||||||
|
mapA[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mapA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (p *PartitioningBy) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
if p.DownStream != nil {
|
||||||
|
result := identity.(map[bool][]interface{})
|
||||||
|
downStreamResult := make(map[bool]interface{})
|
||||||
|
for k, v := range result {
|
||||||
|
downStreamResult[k] = NewStream(v).Collect(p.DownStream)
|
||||||
|
}
|
||||||
|
return downStreamResult
|
||||||
|
}
|
||||||
|
return identity
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
// SummarizingFloat64 对数据集进行统计
|
||||||
|
type SummarizingFloat64 struct {
|
||||||
|
Mapper func(interface{}) float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64SummaryStatistics 数据集统计结果_Float64
|
||||||
|
type Float64SummaryStatistics struct {
|
||||||
|
Min float64
|
||||||
|
Max float64
|
||||||
|
Average float64
|
||||||
|
Sum float64
|
||||||
|
Count int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine 拼装两个结果集
|
||||||
|
func (summary *Float64SummaryStatistics) Combine(other *Float64SummaryStatistics) {
|
||||||
|
if summary.Count == 0 {
|
||||||
|
summary.Max = other.Max
|
||||||
|
summary.Min = other.Max
|
||||||
|
} else if other.Count != 0 {
|
||||||
|
if summary.Max < other.Max {
|
||||||
|
summary.Max = other.Max
|
||||||
|
}
|
||||||
|
if summary.Min > other.Min {
|
||||||
|
summary.Min = other.Min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
summary.Sum += other.Sum
|
||||||
|
summary.Count += other.Count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supplier 提供容器
|
||||||
|
func (summary *SummarizingFloat64) Supplier() func() interface{} {
|
||||||
|
return func() interface{} {
|
||||||
|
return Float64SummaryStatistics{Min: 0, Max: 0, Average: 0, Sum: 0, Count: 0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulator 处理函数
|
||||||
|
func (summary *SummarizingFloat64) Accumulator() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(identity interface{}, element interface{}) interface{} {
|
||||||
|
mid := identity.(Float64SummaryStatistics)
|
||||||
|
value := summary.Mapper(element)
|
||||||
|
if mid.Count == 0 {
|
||||||
|
mid.Max = value
|
||||||
|
mid.Min = value
|
||||||
|
} else {
|
||||||
|
if mid.Max < value {
|
||||||
|
mid.Max = value
|
||||||
|
}
|
||||||
|
if mid.Min > value {
|
||||||
|
mid.Min = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mid.Sum += value
|
||||||
|
mid.Count++
|
||||||
|
return mid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combiner 组装结果
|
||||||
|
func (summary *SummarizingFloat64) Combiner() func(interface{}, interface{}) interface{} {
|
||||||
|
return func(a interface{}, b interface{}) interface{} {
|
||||||
|
midA := a.(Float64SummaryStatistics)
|
||||||
|
midB := b.(Float64SummaryStatistics)
|
||||||
|
midA.Combine(&midB)
|
||||||
|
return midA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finisher 收尾处理
|
||||||
|
func (summary *SummarizingFloat64) Finisher() func(interface{}) interface{} {
|
||||||
|
return func(identity interface{}) interface{} {
|
||||||
|
mid := identity.(Float64SummaryStatistics)
|
||||||
|
mid.Average = mid.Sum / float64(mid.Count)
|
||||||
|
return mid
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package stream
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
// Filter 对任意数组操作,将不合格的元素踢出去
|
||||||
|
func (s *Stream) Filter(predicate func(interface{}) bool) *Stream {
|
||||||
|
ret := make([]interface{}, len(s.list))
|
||||||
|
size := 0
|
||||||
|
if s.isParallel {
|
||||||
|
count := runtime.NumCPU()
|
||||||
|
ch1 := make(chan interface{}, count)
|
||||||
|
ch2 := make(chan interface{})
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
go func() {
|
||||||
|
for true {
|
||||||
|
if value, ok := <-ch1; !ok {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
if predicate(value) {
|
||||||
|
ch2 <- value
|
||||||
|
} else {
|
||||||
|
ch2 <- nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for _, v := range s.list {
|
||||||
|
ch1 <- v
|
||||||
|
}
|
||||||
|
close(ch1)
|
||||||
|
}()
|
||||||
|
for i := 0; i < len(s.list); i++ {
|
||||||
|
value := <-ch2
|
||||||
|
if value != nil {
|
||||||
|
ret[size] = value
|
||||||
|
size++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v := range s.list {
|
||||||
|
if predicate(v) {
|
||||||
|
ret[size] = v
|
||||||
|
size++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.list = ret[:size]
|
||||||
|
return s
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package stream
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
//Map 对任意数组操作,将A包装成B
|
||||||
|
func (s *Stream) Map(mappper func(interface{}) interface{}) *Stream {
|
||||||
|
ret := make([]interface{}, len(s.list))
|
||||||
|
if s.isParallel {
|
||||||
|
count := runtime.NumCPU()
|
||||||
|
ch1 := make(chan interface{}, count)
|
||||||
|
ch2 := make(chan interface{})
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
go func() {
|
||||||
|
for true {
|
||||||
|
if value, ok := <-ch1; !ok {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
ch2 <- mappper(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for _, v := range s.list {
|
||||||
|
ch1 <- v
|
||||||
|
}
|
||||||
|
close(ch1)
|
||||||
|
}()
|
||||||
|
for i := 0; i < len(s.list); i++ {
|
||||||
|
ret[i] = <-ch2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i, v := range s.list {
|
||||||
|
ret[i] = mappper(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.list = ret
|
||||||
|
return s
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package stream
|
||||||
|
|
||||||
|
//Reduce 对任意数组操作,对数组进行降维打击
|
||||||
|
func (s *Stream) Reduce(identity interface{}, accumulator func(interface{}, interface{}) interface{}) interface{} {
|
||||||
|
for _, v := range s.list {
|
||||||
|
identity = accumulator(identity, v)
|
||||||
|
}
|
||||||
|
return identity
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package stream
|
||||||
|
|
||||||
|
// Stream 数据流
|
||||||
|
type Stream struct {
|
||||||
|
isParallel bool
|
||||||
|
list []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parallel 转为并发数据流
|
||||||
|
func (s *Stream) Parallel() *Stream {
|
||||||
|
s.isParallel = true
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sequential 转为单线程数据流
|
||||||
|
func (s *Stream) Sequential() *Stream {
|
||||||
|
s.isParallel = false
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStream 新建数据流
|
||||||
|
func NewStream(list []interface{}) *Stream {
|
||||||
|
return &Stream{list: list, isParallel: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewParallelStream 新建并发数据流
|
||||||
|
func NewParallelStream(list []interface{}) *Stream {
|
||||||
|
return &Stream{list: list, isParallel: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count 统计数量
|
||||||
|
func (s *Stream) Count() int {
|
||||||
|
return len(s.list)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToList 转为列表
|
||||||
|
func (s *Stream) ToList() []interface{} {
|
||||||
|
return s.list
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirst 取得第一条
|
||||||
|
func (s *Stream) FindFirst() interface{} {
|
||||||
|
if len(s.list) > 0 {
|
||||||
|
return s.list[0]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue