自由気ままにブログ

地方零細企業プログラマがひっそりとなにかしています。

Goでcsvファイルをキーにtxtファイルのデータを表示(連想配列)

f:id:nono138:20200421225921p:plain

こんにちは、こんばんは、138nonoです。

Go言語で、csvファイルをキーに、txtファイルのデータとキーが一致したら、表示させるプログラムを組んでみました。

csvファイル(キー)の中身
csvSS

txtファイル(データ)の中身
dataSS

textファイルの:以下のデータを表示させます。
Goの連想配列を利用したソースコードになります。
mainがこちらになります。

package main

import (
    "fmt"
    "encoding/csv"
    "os"
    "bufio"
    "strings"
)
var csvline string //csvデータの文字列配列
var dataline string
var dMap map[string]string //mapの作成
func main() {
    csvPath := "key.csv"
    datePath := "datefile.txt"
    csvline,err := csvRead(csvPath) //csvファイルを、文字列配列に格納
    if err != nil{
        fmt.Println(err)
    }
    dMap,err := dataRead(datePath)//txtファイルを、mapのkeyとvalueをget
    if err != nil{
        fmt.Println(err)
    }
    //fmt.Println(dMap)
    resultMap,err := decide(csvline,dMap)
    if err != nil{
        fmt.Println(err)
    }
    //fmt.Println(resultMap)
    for i:= 0; i < len(csvline); i++{
        fmt.Println(csvline[i],resultMap[csvline[i]])
    }
}

csvファイルを、文字列配列に格納する関数

//csvを読み込み配列にセット
func csvRead(csvPath string)(line string,err error){
    file,err := os.Open(csvPath) //csvを開く
    if err != nil{
        fmt.Println(err)
    }
    defer file.Close()
    
    reader := csv.NewReader(file)   //csvの読み込み
    for {
        lineerr = reader.Read()
        if err != nil {
            break
        }
        csvline = line //戻り値用の値にcsvデータをループの数だけ、挿入
    }
    return csvline, nil
}

txtファイルのデータ、mapに入れる関数

//データの読み込みとkeyの判定をし、:以降のkeyをstringで返す
func dataRead(datePath string)(dMap map[string]string, err error){
    var lines string
    dMap = map[string]string{} //mapの初期化 (mapは初期化しないと、panicが起きる為)
    fileerr := os.Open(datePath)
    if err != nil {
        fmt.Println(err)
    }
    //textファイルをスキャン
    scanner := bufio.NewScanner(file)
    //スキャン出来るでけ、ループ
    for i :=0; scanner.Scan(); i++ {
        lines = append(lines, scanner.Text())
        //fmt.Println(lines[i])
        dataline = lines
        if strings.Contains(dataline[i], ":"){
            //:の位置を取得
            s := strings.Index(dataline[i], ":")
            //:の位置以前・以降を切り捨て
            datakey := dataline[i][:s] //:以前
            datavalue := dataline[i][s+1:] //以降
            dMap[datakey] = datavalue
        }
        if err != nil {
            return dMap, err
        }
    }
    return dMap,nil
}

csvのキーと一致するmapを判定する関数

//mapのkeyの判定,戻り値はmap
func decide(csvline string,dMap map[string]string)(resultMap map[string]string,err error){
    resultMap = map[string]string{}
    for i:=0; i <len(csvline); i++{
        resultMap[csvline[i]] = dMap[csvline[i]]
    }
    if err != nil {
        return resultMap,err
    }
    return resultMap,nil
}

実行結果

愛知 名古屋 岐阜 岐阜 三重 津 滋賀 大津 東京 東京


以前、Go言語では、連想配列を使わず、構造体に入れた方が良いとされて明言しましたが、JAVAを学んでいた時、あまりmapを使わなかったので、Goで触ってみましたが、なかなか便利ですね

なお、今回はcsvの順番通りに表示させるように処理がされていますが、mapだけで使うときは、順番がランダムになるので注意して下さい。

まだ、プログラミングを学んで半年経たずの半端者ですが、皆さんと知識を共有できたらなと思います。
コードのここをこうした方が良いよなど、改善ポイントも絶賛受付中なので、ご教授お願い致します。