-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfrom.go
159 lines (133 loc) · 3.05 KB
/
from.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
package flinx
// Iterator is an alias for function to iterate over data.
type Iterator[T any] func() (item T, ok bool)
// Query is the type returned from query functions. It can be iterated manually
// as shown in the example.
type Query[T any] struct {
Iterate func() Iterator[T]
}
// KeyValue is a type that is used to iterate over a map (if query is created
// from a map). This type is also used by ToMap() method to output result of a
// query into a map.
type KeyValue[K comparable, V any] struct {
Key K
Value V
}
func FromSlice[T any](source []T) Query[T] {
length := len(source)
return Query[T]{
Iterate: func() Iterator[T] {
index := 0
return func() (item T, ok bool) {
ok = index < length
if ok {
item = source[index]
index++
}
return
}
},
}
}
func FromMap[K comparable, V any](source map[K]V) Query[KeyValue[K, V]] {
length := len(source)
keys := make([]K, length)
idx := 0
for k := range source {
keys[idx] = k
idx++
}
return Query[KeyValue[K, V]]{
Iterate: func() Iterator[KeyValue[K, V]] {
index := 0
return func() (item KeyValue[K, V], ok bool) {
ok = index < length
if ok {
key := keys[index]
item = KeyValue[K, V]{
Key: key,
Value: source[key],
}
index++
}
return
}
},
}
}
// FromChannel initializes a linq query with passed channel, linq iterates over
// channel until it is closed.
func FromChannel[T any](source <-chan T) Query[T] {
return Query[T]{
Iterate: func() Iterator[T] {
return func() (item T, ok bool) {
item, ok = <-source
return
}
},
}
}
// FromString initializes a linq query with passed string, linq iterates over
// runes of string.
func FromString(source string) Query[rune] {
runes := []rune(source)
length := len(source)
return Query[rune]{
Iterate: func() Iterator[rune] {
index := 0
return func() (item rune, ok bool) {
ok = index < length
if ok {
item = runes[index]
index++
}
return
}
},
}
}
// FromIterable initializes a linq query with custom collection passed. This
// collection has to implement Iterable interface, linq iterates over items,
// that has to implement Comparable interface or be basic types.
func FromIterable[T any](sourceFunc Iterator[T]) Query[T] {
return Query[T]{
Iterate: func() Iterator[T] {
return sourceFunc
},
}
}
// Range generates a sequence of integral numbers within a specified range.
func Range(start, count int) Query[int] {
return Query[int]{
Iterate: func() Iterator[int] {
index := 0
current := start
return func() (item int, ok bool) {
if index >= count {
return 0, false
}
item, ok = current, true
index++
current++
return
}
},
}
}
// Repeat generates a sequence that contains one repeated value.
func Repeat[T any](value T, count int) Query[T] {
return Query[T]{
Iterate: func() Iterator[T] {
index := 0
return func() (item T, ok bool) {
if index >= count {
var r T
return r, false
}
item, ok = value, true
index++
return
}
},
}
}