随笔 - 56  文章 - 0 评论 - 0 阅读 - 50707

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
191
192
193
194
195
196
197
198
199
200
201
202
203
package stream
 
import (
    "fmt"
    "reflect"
    "strings"
)
 
type T interface{}
 
type U interface{}
 
//流计算数据结构定义
type Stream struct {
    Head     T
    Tail     *Stream
    Length   int
    NotEmpty bool
}
 
var Nil = Stream{}
 
func Generate(r Stream, f func(Stream) T, m int) Stream {
 
    if m == 1 {
        return r
    }
 
    return Generate(New(f(r), &r), f, m-1)
}
 
func From(i ...T) Stream {
 
    return Nil.Addall(i...)
 
}
 
var IntSlice = func(value reflect.Value) U {
    return value.Int()
}
 
func FromSlice(i T, f func(reflect.Value) U) Stream {
 
    s := Nil
    v := reflect.ValueOf(i)
 
    n := v.Len()
 
    for i := 0; i < n; i++ {
        s = s.Add(f(v.Index(i)))
    }
 
    return s
 
}
 
func New(head T, tail *Stream) Stream {
 
    return Stream{head, tail, tail.Length + 1, true}
 
}
 
func (s Stream) Add(i T) Stream {
 
    return New(i, &s)
 
}
 
func (s Stream) Addall(i ...T) Stream {
 
    for _, v := range i {
        s = s.Add(v)
    }
 
    return s
 
}
 
//左折叠 用于实现 reduce 的功能
func (s Stream) FoldLeft(i U, f func(U, T) U) U {
 
    if s.NotEmpty {
        return s.Tail.FoldLeft(f(i, s.Head), f)
    }
 
    return i
}
 
//右折叠
func (s Stream) FoldRight(i U, f func(U, T) U) U {
 
    if s.NotEmpty {
        return f(s.Tail.FoldRight(i, f), s.Head)
    }
 
    return i
}
 
//合并两个 Stream
func (s Stream) Merge(t Stream) Stream {
 
    if t.NotEmpty {
        return t.FoldRight(s, func(u U, t T) U {
            return u.(Stream).Add(t)
        }).(Stream)
 
    }
 
    return s
}
 
//倒序
func (s Stream) Reverse() Stream {
 
    return s.FoldLeft(Nil, func(u U, t T) U {
        return u.(Stream).Add(t)
    }).(Stream)
 
}
 
//Map
func (s Stream) Map(f func(T) U) Stream {
 
    return s.FoldRight(Nil, func(u U, t T) U {
        return u.(Stream).Add(f(t))
    }).(Stream)
 
}
 
//Reduce
func (s Stream) Reduce(i T, f func(t1,t2 T) T) T {
 
    if s.NotEmpty {
        return s.Tail.Reduce(f(i, s.Head), f)
    }
 
    return i
}
 
//过滤
func (s Stream) Filter(f func(T) bool) Stream {
 
    return s.FoldRight(Nil, func(u U, t T) U {
 
        if f(t) {
            return u.(Stream).Add(t)
        }
 
        return u
 
    }).(Stream)
 
}
 
//归并排序
func (s Stream) Sort(c func(t1,t2 T) bool) Stream {
 
    n := s.Length / 2
 
    if n == 0 {
        return s
    }
 
    x, y := split(s, Nil, n)
    return merge(x.Sort(c), y.Sort(c), c)
}
 
func split(x, y Stream, n int) (Stream, Stream) {
 
    if n == 0 || !x.NotEmpty {
        return x, y
    }
 
    return split(*x.Tail, y.Add(x.Head), n-1);
}
 
func merge(x, y Stream, c func(t1,t2 T) bool) Stream {
 
    if !x.NotEmpty {
        return y
    }
 
    if !y.NotEmpty {
        return x
    }
 
    if c(x.Head, y.Head) {
        return merge(*x.Tail, y, c).Add(x.Head)
    }
 
    return merge(x, *y.Tail, c).Add(y.Head);
}
 
//格式化显示 Stream 的所有项
func (s Stream) ToString() string {
 
    return "{" + strings.Join(s.FoldRight([]string{}, func(u U, t T) U {
        return append(u.([]string), fmt.Sprintf("%v", t))
    }).([]string), ",") + "}"
 
}
 
///////////////////////////////////

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
package main
 
import (
    "./stream"
    "fmt"
    "strings"
)
 
func main() {
 
    x := stream.Generate(stream.Nil.Add(1), func(s stream.Stream) stream.T { return s.Head.(int) + 1 }, 50) // {1,2,3,...,48,49,50}
    x = x.Map(func(t stream.T) stream.U {
        p := t.(int) //平方映射
        return p * p
    }).Filter(func(t stream.T) bool {
        return t.(int)%2 == 0 //偶数过滤
    })
 
    //计算所有项的和
    fmt.Printf("sum %s = %d\n", x.ToString(), x.FoldLeft(0, func(u stream.U, t stream.T) stream.U {
        return u.(int) + t.(int)
    })) //22100
 
    //浮点数列表求和
    y := stream.From(3.5, 4.3, 2.6, 1.1, 7.83, 4.42)
    fmt.Printf("%.2f\n", y.Reduce(0.0, func(t, t2 stream.T) stream.T {
        return t.(float64) + t2.(float64)
    }))
 
    //排序
    z := stream.From(4, 3, 7, 6, 2, 1, 9, 5, 8, 0).Sort(func(x, y stream.T) bool {
        return x.(int) > y.(int)
    })
    fmt.Println(z.ToString()) //{0,1,2,3,4,5,6,7,8,9}
 
    //列出包含a字符的字符串
    g := stream.From("aaa", "bbb", "aba", "ccc", "cbb", "cba")
    fmt.Println(g.Filter(func(t stream.T) bool {
        return strings.Contains(t.(string), "a")
    }).ToString())
 
    //生成斐波拉契亚数列 的前 20 项
    fmt.Println(stream.Generate(stream.From(1, 1), func(s stream.Stream) stream.T {
        return s.Head.(int) + s.Tail.Head.(int)
    }, 19).ToString())
 
    //通过数列 π = 2 + 2/3 + 2/3*2/5 + 2/3*2/5*3/7  + ... + f(n-1) * n/(2*n+1) 计算圆周率的值
    fmt.Println(stream.Generate(stream.From(2.0), func(s stream.Stream) stream.T {
        n := s.Length
        return s.Head.(float64) * float64(n) / (float64(n)*2 + 1)
    }, 51).Reduce(0.0, func(t, t2 stream.T) stream.T {
        return t.(float64) + t2.(float64)
    }))
 
    fmt.Println(stream.From(1, 2, 3, 4, 5).Reduce(0, func(t1, t2 stream.T) stream.T {
        return t1.(int) + t2.(int)
    }))
 
    k := []int{1, 2, 3, 4, 5}
    p := stream.FromSlice(k, stream.IntSlice)
 
    fmt.Println(p.Reduce(int64(0), func(t1, t2 stream.T) stream.T {
        return t1.(int64) + t2.(int64)
    }))
 
}
 
///////////////////////////////////
posted on   scala  阅读(862)  评论(0编辑  收藏  举报
编辑推荐:
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· 继承的思维:从思维模式到架构设计的深度解析
阅读排行:
· 【保姆级教程】windows 安装 docker 全流程
· 基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
· 由 MCP 官方推出的 C# SDK,使 .NET 应用程序、服务和库能够快速实现与 MCP 客户端
· 电商平台中订单未支付过期如何实现自动关单?
· 上周热点回顾(3.31-4.6)
点击右上角即可分享
微信分享提示