-
Notifications
You must be signed in to change notification settings - Fork 11
/
factory.go
190 lines (173 loc) · 4.72 KB
/
factory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package stream
import (
"errors"
"reflect"
"github.com/youthlin/stream/optional"
"github.com/youthlin/stream/types"
)
var (
// ErrNotSlice a error to panic when call Slice but argument is not slice
ErrNotSlice = errors.New("not slice")
ErrNotMap = errors.New("not map")
)
// Slice 把任意的切片类型转为[]T类型. 可用作 Of() 入参.
// Slice convert any slice type to []types.T e.g. []int -> []types.T. may used with Of().
// Note: cannot use ints (type []int) as type []types.T in argument to streams.Of
func Slice(slice types.T) []types.T {
if reflect.TypeOf(slice).Kind() != reflect.Slice {
panic(ErrNotSlice)
}
var result []types.T
value := reflect.ValueOf(slice)
count := value.Len()
for i := 0; i < count; i++ {
result = append(result, value.Index(i).Interface())
}
return result
}
// Entries 把任意的 map 类型转为 []Pair
// Entries return entries of a map as []types.Pair which `First` field is key, `Second` field is value
func Entries(mapValue types.T) []types.Pair {
if reflect.TypeOf(mapValue).Kind() != reflect.Map {
panic(ErrNotMap)
}
value := reflect.ValueOf(mapValue)
var result []types.Pair
var it = value.MapRange()
for it.Next() {
result = append(result, types.Pair{
First: it.Key().Interface(),
Second: it.Value().Interface(),
})
}
return result
}
// Of create a Stream from some element
// It's recommend to pass pointer type cause the element may be copy at each operate
func Of(elements ...types.T) Stream {
return newHead(it(elements...))
}
func OfInts(element ...int) Stream {
return newHead(&intsIt{
base: &base{
current: 0,
size: len(element),
},
elements: element,
})
}
func OfInt64s(element ...int64) Stream {
return newHead(&int64sIt{
base: &base{
current: 0,
size: len(element),
},
elements: element,
})
}
func OfFloat32s(element ...float32) Stream {
return newHead(&float32sIt{
base: &base{
current: 0,
size: len(element),
},
elements: element,
})
}
func OfFloat64s(element ...float64) Stream {
return newHead(&float64sIt{
base: &base{
current: 0,
size: len(element),
},
elements: element,
})
}
func OfStrings(element ...string) Stream {
return newHead(&stringIt{
base: &base{
current: 0,
size: len(element),
},
elements: element,
})
}
// OfSlice return a Stream. the input parameter `slice` must be a slice.
// if input is nil, return a empty Stream( same as Of() )
func OfSlice(slice types.T) Stream {
if optional.IsNil(slice) {
return Of()
}
if reflect.TypeOf(slice).Kind() != reflect.Slice {
panic(ErrNotSlice)
}
value := reflect.ValueOf(slice)
it := &sliceIt{
base: &base{
current: 0,
size: value.Len(),
},
sliceValue: value,
}
return newHead(it)
}
// OfMap return a Stream which element type is types.Pair.
// the input parameter `mapValue` must be a map or it will panic
// if mapValue is nil, return a empty Stream ( same as Of() )
func OfMap(mapValue types.T) Stream {
if optional.IsNil(mapValue) {
return Of()
}
if reflect.TypeOf(mapValue).Kind() != reflect.Map {
panic(ErrNotMap)
}
value := reflect.ValueOf(mapValue)
it := &mapIt{
base: &base{
current: 0,
size: value.Len(),
},
mapValue: value.MapRange(),
}
return newHead(it)
}
// Iterate create a Stream by a seed and an UnaryOperator
func Iterate(seed types.T, operator types.UnaryOperator) Stream {
return newHead(withSeed(seed, operator))
}
// Generate generates a infinite Stream which each element is generate by Supplier
func Generate(get types.Supplier) Stream {
return newHead(withSupplier(get))
}
// Repeat returns a infinite Stream which all element is same
func Repeat(e types.T) Stream {
return newHead(withSupplier(func() types.T {
return e
}))
}
// RepeatN returns a Stream which has `count` element and all the element is the given `e`
func RepeatN(e types.T, count int64) Stream {
return Repeat(e).Limit(count)
}
// IntRange creates a Stream which element is the given range
func IntRange(fromInclude, toExclude int) Stream {
return IntRangeStep(fromInclude, toExclude, 1)
}
// IntRangeStep creates a Stream which element is the given range by step
func IntRangeStep(fromInclude, toExclude, step int) Stream {
return newHead(withRange(epInt(fromInclude), epInt(toExclude), step)).Map(func(t types.T) types.R {
// streams.epInt is not int
// 所以转回 int 让调用方不至于迷惑
return int(t.(epInt))
})
}
// Int64Range like IntRange
func Int64Range(fromInclude, toExclude int64) Stream {
return Int64RangeStep(fromInclude, toExclude, 1)
}
// Int64RangeStep like IntRangeStep
func Int64RangeStep(fromInclude, toExclude int64, step int) Stream {
return newHead(withRange(epInt64(fromInclude), epInt64(toExclude), step)).Map(func(t types.T) types.R {
return int64(t.(epInt64))
})
}