簡體   English   中英

使用 csv 在單值上下文中處理多值讀取

[英]handling multiple-value in single-value context with csv read

試圖從 csv 文件中讀取datenumber ,所以我有以下結構

type Transaction struct {
    Warehouse string    `json:"warehouse"`
    Item      string    `json:"item"`
    Movement  string    `json:"movement"`
    Batch     string    `json:"batch"`
    Date      time.Time `json:"transaction_data"`
    Quantity  uint64    `json:"quantity"`
}

type Transactions struct {
    header []string
    lines  []Transaction
}

並進行如下閱讀:

func main() {
    // Reading csv file thread > START //
    pairs := []Pair{{"m", 1}, {"d", 0}, {"c", 2}}
    fmt.Println(pairs)
    // Sort by Key
    sort.Sort(ByKey(pairs))
    fmt.Println(pairs)
    pairs = append(pairs, Pair{"h", 5})
    fmt.Println(pairs)

    // Reading csv file thread > START //
    input := make(chan Transactions)
    go func(input_file string) {
        var trx Transactions
        fr, err := os.Open(input_file)
        failOnError(err)
        defer fr.Close()
        r := csv.NewReader(fr)
        rows, err := r.ReadAll()
        failOnError(err)
        trx.header = rows[0]
        for _, row := range rows[1:] {
            trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      time.Parse("%Y-%m-%d", row[4]),                   // multiple-value in single-value context error
                Quantity:  (strconv.ParseFloat(row[5], 64) * 1000).(uint64),  // multiple-value in single-value context error
            })
        }

        peopleJson, _ := json.Marshal(trx.lines)
        fmt.Println(string(peopleJson)) 

        input <- trx // send data to channel read
    }("trx.csv")
    <-input // rceive from channel 'read' and assign value to new data variable
    // Reading csv file thread < END //
}

並得到2個錯誤:

.\pair.go:73:24: multiple-value time.Parse() in single-value context
.\pair.go:74:34: multiple-value strconv.ParseFloat() in single-value context

我理解原因,這是 time.Parse( time.Parse()strconv.ParseFloat()返回 2 個輸出、值和錯誤,並且可以通過編寫來克服這個問題:

date, _ := time.Parse("%Y-%m-%d", row[4])
// and later:
Date:      date,

但我想知道我是否可以避免這種情況,並在同一個命令塊中解決它:

trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      ...
                Quantity:  ...
}

我得到了答案(感謝富有成效的評論,只有富有成效的評論)

解決方案制作一個單獨的 function 讀取 2 上下文,並僅返回如下值:

func mustTime(t time.Time, err error) time.Time { failOnError(err); return t }
func mustNumber(d float64, err error) uint64    { failOnError(err); return uint64(d + 1000) }

然后將其稱為:

Date:      mustTime(time.Parse("%Y-%m-%d", row[4])),
Quantity:  mustNumber(strconv.ParseFloat(row[5], 64)),

因此,完整正確的代碼變為:

package main

import (
    "encoding/csv"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "sort"
    "strconv"
    "strings"
    "time"
)

func failOnError(err error) {
    if err != nil {
        log.Fatal("Error:", err)
        panic(err)
    }
}

type Pair struct {
    Key   string
    Value float64
}

type ByKey []Pair

func (s ByKey) Len() int {
    return len(s)
}

func (s ByKey) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func (s ByKey) Less(i, j int) bool {
    return s[i].Key < s[j].Key
}

func (s ByKey) pop() bool {
    //s = append(s,[0 : s.Len()-1])
    return true
}

func main() {
    // Reading csv file thread > START //
    pairs := []Pair{{"m", 1}, {"d", 0}, {"c", 2}}
    fmt.Println(pairs)
    // Sort by Key
    sort.Sort(ByKey(pairs))
    fmt.Println(pairs)
    pairs = append(pairs, Pair{"h", 5})
    fmt.Println(pairs)

    // Reading csv file thread > START //
    input := make(chan Transactions)
    go func(input_file string) {
        var trx Transactions
        fr, err := os.Open(input_file)
        failOnError(err)
        defer fr.Close()
        r := csv.NewReader(fr)
        rows, err := r.ReadAll()
        failOnError(err)
        trx.header = rows[0]
        for _, row := range rows[1:] {
            trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      mustTime(time.Parse("%Y-%m-%d", row[4])),
                Quantity:  mustNumber(strconv.ParseFloat(row[5], 64)),
            })
        }

        peopleJson, _ := json.Marshal(trx.lines)
        fmt.Println(string(peopleJson)) // This is working smoothly

        input <- trx // send data to channel read
    }("trx.csv")
    //data :=
    <-input // rceive from channel 'read' and assign value to new data variable
    // Reading csv file thread < END //
}

type Transactions struct {
    header []string
    lines  []Transaction
}

type Transaction struct {
    Warehouse string    `json:"warehouse"`
    Item      string    `json:"item"`
    Movement  string    `json:"movement"`
    Batch     string    `json:"batch"`
    Date      time.Time `json:"transaction_data"`
    Quantity  uint64    `json:"quantity"`
}

func mustTime(t time.Time, err error) time.Time { failOnError(err); return t }
func mustNumber(d float64, err error) uint64    { failOnError(err); return uint64(d + 1000) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM