编写深度为 d 的嵌套迭代器
Writing a nested iterator of depth d
如何实现带有深度参数的嵌套迭代器。一个简单的迭代器将在深度 = 1 时出现。它是一个像简单的 for 循环一样运行的简单迭代器。
func Iter () chan int {
ch := make(chan int);
go func () {
for i := 1; i < 60; i++ {
ch <- i
}
close(ch)
} ();
return ch
}
输出为1,2,3...59
对于深度 = 2 输出将是 "1,1" "1,2" ... "1,59" "2,1" ... "59,59"
对于深度 = 3 输出将是 "1,1,1" ... "59,59,59
"
我想避免嵌套的 for 循环。这里的解决方案是什么?
我不知道是否可以避免嵌套循环,但一种解决方案是使用通道管道。例如:
const ITER_N = 60
// ----------------
func _goFunc1(out chan string) {
for i := 1; i < ITER_N; i++ {
out <- fmt.Sprintf("%d", i)
}
close(out)
}
func _goFuncN(in chan string, out chan string) {
for j := range in {
for i := 1; i < ITER_N; i++ {
out <- fmt.Sprintf("%s,%d", j, i)
}
}
close(out)
}
// ----------------
// create the pipeline
func IterDepth(d int) chan string {
c1 := make(chan string)
go _goFunc1(c1)
var c2 chan string
for ; d > 1; d-- {
c2 = make(chan string)
go _goFuncN(c1, c2)
c1 = c2
}
return c1
}
您可以通过以下方式进行测试:
func main() {
c := IterDepth(2)
for i := range c {
fmt.Println(i)
}
}
我通常使用闭包实现迭代器。多个维度不会使问题变得更难。这是如何执行此操作的一个示例:
package main
import "fmt"
func iter(min, max, depth int) func() ([]int, bool) {
s := make([]int, depth)
for i := range s {
s[i] = min
}
s[0] = min - 1
return func() ([]int, bool) {
s[0]++
for i := 0; i < depth-1; i++ {
if s[i] >= max {
s[i] = min
s[i+1]++
}
}
if s[depth-1] >= max {
return nil, false
}
return s, true
}
}
func main() {
// Three dimensions, ranging between [1,4)
i := iter(1, 4, 3)
for s, ok := i(); ok; s, ok = i() {
fmt.Println(s)
}
}
在 Playground 上试用。
这将是一个简单的更改,例如,将参数作为单个 int 切片提供,这样您就可以有每个维度的限制,如果有必要的话。
如何实现带有深度参数的嵌套迭代器。一个简单的迭代器将在深度 = 1 时出现。它是一个像简单的 for 循环一样运行的简单迭代器。
func Iter () chan int {
ch := make(chan int);
go func () {
for i := 1; i < 60; i++ {
ch <- i
}
close(ch)
} ();
return ch
}
输出为1,2,3...59
对于深度 = 2 输出将是 "1,1" "1,2" ... "1,59" "2,1" ... "59,59"
对于深度 = 3 输出将是 "1,1,1" ... "59,59,59
"
我想避免嵌套的 for 循环。这里的解决方案是什么?
我不知道是否可以避免嵌套循环,但一种解决方案是使用通道管道。例如:
const ITER_N = 60
// ----------------
func _goFunc1(out chan string) {
for i := 1; i < ITER_N; i++ {
out <- fmt.Sprintf("%d", i)
}
close(out)
}
func _goFuncN(in chan string, out chan string) {
for j := range in {
for i := 1; i < ITER_N; i++ {
out <- fmt.Sprintf("%s,%d", j, i)
}
}
close(out)
}
// ----------------
// create the pipeline
func IterDepth(d int) chan string {
c1 := make(chan string)
go _goFunc1(c1)
var c2 chan string
for ; d > 1; d-- {
c2 = make(chan string)
go _goFuncN(c1, c2)
c1 = c2
}
return c1
}
您可以通过以下方式进行测试:
func main() {
c := IterDepth(2)
for i := range c {
fmt.Println(i)
}
}
我通常使用闭包实现迭代器。多个维度不会使问题变得更难。这是如何执行此操作的一个示例:
package main
import "fmt"
func iter(min, max, depth int) func() ([]int, bool) {
s := make([]int, depth)
for i := range s {
s[i] = min
}
s[0] = min - 1
return func() ([]int, bool) {
s[0]++
for i := 0; i < depth-1; i++ {
if s[i] >= max {
s[i] = min
s[i+1]++
}
}
if s[depth-1] >= max {
return nil, false
}
return s, true
}
}
func main() {
// Three dimensions, ranging between [1,4)
i := iter(1, 4, 3)
for s, ok := i(); ok; s, ok = i() {
fmt.Println(s)
}
}
在 Playground 上试用。
这将是一个简单的更改,例如,将参数作为单个 int 切片提供,这样您就可以有每个维度的限制,如果有必要的话。