JohnStephen.19
JohnStephen.19

Reputation: 363

How to repeatedly call a function for each iteration in a loop, get its results then append the results into a slice (Golang?

I have the ff:

func getSlice(distinctSymbols []string) []symbols {
    // Prepare connection
    stmt1, err := db.Prepare("Select count(*) from stockticker_daily where symbol = $1;")
    checkError(err)
    defer stmt1.Close()
    stmt2, err := db.Prepare("Select date from stockticker_daily where symbol = $1 order by date asc limit 1;")
    checkError(err)
    defer stmt2.Close()
    var symbolsSlice []symbols
    c := make(chan symbols)
    for _, symbol := range distinctSymbols {
        go worker(symbol, stmt1, stmt2, c)
        **symbolsFromChannel := <-c**
        **symbolsSlice = append(symbolsSlice, symbolsFromChannel})**
    }
    return symbolsSlice
}

func worker(symbol string, stmt1 *sql.Stmt, stmt2 *sql.Stmt, symbolsChan chan symbols) {
    var countdp int
    var earliestdate string
    row := stmt1.QueryRow(symbol)
    if err := row.Scan(&countdp); err != nil {
        log.Fatal(err)
    }
    row = stmt2.QueryRow(symbol)
    if err := row.Scan(&earliestdate); err != nil {
        log.Fatal(err)
    }
    symbolsChan <- symbols{symbol, countdp, earliestdate}
}

Please take a look at the first function, I know it won't work as I expect since the line symbolsFromChannel := <-c will block until it receives from the channel, so the iteration on the goroutine go worker will not continue unless the block is removed. What is the best or correct way to do that?

Upvotes: 1

Views: 295

Answers (1)

superfell
superfell

Reputation: 19040

Just do the loop twice, e.g.

for _, symbol := range distinctSymbols {
        go worker(symbol, stmt1, stmt2, c)
}
for range distinctSymbols {
        symbolsSlice = append(symbolsSlice, <-c)
}

Upvotes: 1

Related Questions