2016-02-22 37 views
1

如何實現採用深度參數的嵌套迭代器。一個簡單的迭代器就是depth = 1的時候。它是一個簡單的迭代器,它像一個簡單的for循環一樣運行。編寫深度爲d的嵌套迭代器

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循環。這是在這裏的解決方案?

+0

爲什麼你想避免嵌套循環?如果'Iter()'採用'depth'參數,那麼返回類型是什麼? – icza

+0

@icza嵌套循環不讓我寫深度d的泛型迭代器?我很喜歡字符串,加入的是int, – user568109

+0

@ user568109:在Go標準庫中使用goroutine迭代器的早期實驗被放棄了。你爲什麼想這樣做? – peterSO

回答

2

我不知道是否有可能避免嵌套循環,但一種解決方案是使用渠道管道。例如:

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) 
    } 
} 
+0

作品。這是我正在尋找的。我沒有知道這個術語叫做流水線。 – user568109

1

我通常使用閉包實現迭代器。多維度不會使問題變得更難。下面是如何做到這一點的一個例子:

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切片,以便您可以擁有每個維度的限制,如果有必要的話。