forked from go-gota/gota
/
wrap.go
92 lines (85 loc) · 1.97 KB
/
wrap.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
package series
//Wrapper define special operations for multiple Series
type Wrapper interface {
FloatApply(f func(thisValue float64, wrapValues []float64) float64) Series
BoolApply(f func(thisValue bool, wrapValues []bool) bool) Series
}
//wrapper implements Wrapper
type wrapper struct {
thisSeries Series
ss []Series
}
func newWrapper(this Series, ss []Series) Wrapper {
if len(ss) > 0 {
expectedLen := this.Len()
for i := 0; i < len(ss); i++ {
if expectedLen != ss[i].Len() {
panic("wrappered series must have the same length")
}
}
}
w := wrapper{thisSeries: this, ss: ss}
return w
}
func (w wrapper) FloatApply(f func(thisValue float64, wrapValues []float64) float64) Series {
length := w.thisSeries.Len()
elements := make(floatElements, length)
for i := 0; i < length; i++ {
elements[i].SetFloat(f(w.thisSeries.Elem(i).Float(), rowFloats(i, w.ss)))
}
ret := &series{
name: "",
elements: elements,
t: Float,
err: nil,
}
return ret
}
func (w wrapper) BoolApply(f func(thisValue bool, wrapValues []bool) bool) Series {
length := w.thisSeries.Len()
elements := make(boolElements, length)
for i := 0; i < length; i++ {
thisB, err := w.thisSeries.Elem(i).Bool()
if err != nil {
return Err(err)
}
wrapBs, err := rowBools(i, w.ss)
if err != nil {
return Err(err)
}
elements[i].SetBool(f(thisB, wrapBs))
}
ret := &series{
name: "",
elements: elements,
t: Bool,
err: nil,
}
return ret
}
func rowBools(index int, ss []Series) ([]bool, error) {
length := len(ss)
if length == 0 {
return nil, nil
}
ret := make([]bool, length)
var err error
for i := 0; i < length; i++ {
ret[i], err = ss[i].Elem(index).Bool()
if err != nil {
return nil, err
}
}
return ret, nil
}
func rowFloats(index int, ss []Series) []float64 {
length := len(ss)
if length == 0 {
return nil
}
ret := make([]float64, length)
for i := 0; i < length; i++ {
ret[i] = ss[i].Elem(index).Float()
}
return ret
}