如何通过检入Golang解决此迭代?

时间:2018-06-08 10:25:59

标签: go concurrency

我有一些Golang代码,如下所示

package main

type MyStruct struct {
    field1 string
    field2 float64
    field3 int
    field4 bool
}

func main() {
    names := getNames()
    myStruct := getMyStruct(names)
    writeToCsv(myStruct)
}

func getNames() []string {
    // get list of names then return
}

func getMyStruct(names []string) []Mystruct {
    myStruct := []MyStruct{}
    for i := range names {
        // do something then assign the computed values
        myStruct = append(myStruct, MyStruct{
            field1: value1,
            field2: value2,
            field3: value3,
            field4: value4,
        })
    }
    return myStruct
}

func writeToCsv(myStruct []MyStruct) {
    // prepare writer then write header
    for i := range myStruct {
        // create the slice of string to be written to csv
    }
}

它正常工作。但是,我希望能够将单个csv文件中写入的行数限制为例如500,000行没有相同的name行(来自names切片)被分开。

例如,name1有200,000个MyStruct行,name2有289,000个MyStruct行,name3有180,000个MyStruct行。由于从name1name3的总行数已超过500,000,我希望将其写入单个csv文件中。之后,我想继续获取name4name5等的MyStruct数据,依此类推,直到它们的总数再次超过500,000。

另外,由于我正在使用Golang,我认为如果我也知道如何同时执行以下操作会更好:

1. Get the MyStruct rows
2. Write them to CSV

感谢您的帮助。

Edit1:如果有人可以告诉我如何使用闭包来解决上述问题(我认为这可能是一个可能的解决方案),我将非常感激。

1 个答案:

答案 0 :(得分:0)

假设你的结构是按顺序生成的,那就是设置一个行的计数器并记住之前的值。

func generate(structs []MyStruct) {
    var count = 0
    var previous = structs[0].name

    for _, s := range structs {
        if s.name != previous && count > 500000 {
            // flush your csv here
            count = 0
        }

        // append to your buffer here

        previous = s.name
    }
}

要同时执行此操作,您需要查看频道和goroutines。

例如

func makeStructs(names []string) chan MyStruct {
    var c = make(chan MyStruct)
    go func() {
        for _, n := range names {
            // do you thing
            c <- struct{...}
        }
        close(c)
    }()
}

func generate(structs chan MyStruct) {
    var count = 0
    var previous = ""

    for s := range structs {
        if s.name != previous && count > 500000 {
            // flush your csv here
            count = 0
        }

        // append to your buffer here

        previous = s.name
    }
}