Как мне решить эту итерацию с проверкой в ​​Голанге? - PullRequest
0 голосов
/ 08 июня 2018

У меня есть несколько кодов Голанга, которые выглядят следующим образом

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.Поскольку общее число строк от name1 до name3 уже превышает 500 000, я бы хотел, чтобы оно было записано в одном файле CSV.После этого я хотел бы продолжить получать данные MyStruct для name4, name5 и т. Д. И т. Д., Пока их общее число снова не превысит 500 000.

Кроме того, поскольку я использую Golang, я думаю,было бы лучше, если бы я также знал, как сделать следующее одновременно:

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

Спасибо за помощь.

Edit1: Если кто-то может показать мне, как использовать замыкания для вышеуказанной проблемы(что, я думаю, может быть возможным решением), я буду признателен за это.

1 Ответ

0 голосов
/ 08 июня 2018

Предполагая, что ваши структуры сгенерированы по порядку, уловка заключается в том, чтобы иметь счетчик для строк и запомнить предыдущее значение.

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
    }
}

Для одновременного выполнения этого вы хотите посмотреть на каналы и программы.

Например

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...