2017-09-10 2 views
2

J'essaye d'écrire un script Go qui prend autant de lignes de coordonnées séparées par des virgules que l'utilisateur le souhaite, scinde et convertit la chaîne de coordonnées en float64 , stockez chaque ligne comme une tranche, puis ajoutez chaque tranche dans une tranche de tranches pour une utilisation ultérieure.Golang - Convertir une tranche d'entrée de chaîne de la console à une tranche de nombres

entrées Exemple sont:

1.1,2.2,3.3 
3.14,0,5.16 

sorties Exemple sont:

[[1.1 2.2 3.3],[3.14 0 5.16]] 

L'équivalent en Python est

def get_input(): 
    print("Please enter comma separated coordinates:") 
    lines = [] 
    while True: 
     line = input() 
     if line: 
      line = [float(x) for x in line.replace(" ", "").split(",")] 
      lines.append(line) 
     else: 
      break 
    return lines 

Mais ce que j'ai écrit dans Go semble trop longtemps (collé ci-dessous), et je crée beaucoup de variables sans la possibilité de changer le type de variable comme en Python. Depuis que j'ai littéralement commencé à écrire Golang pour l'apprendre, je crains que mon script soit long car j'essaie de convertir Python en Go. Par conséquent, je voudrais demander quelques conseils sur la façon d'écrire ce script plus court et plus concis dans le style Go? Je vous remercie.

package main 

import (
    "fmt" 
    "os" 
    "bufio" 
    "strings" 
    "strconv" 
) 

func main() { 
    inputs := get_input() 
    fmt.Println(inputs) 
} 

func get_input() [][]float64 { 
    fmt.Println("Please enter comma separated coordinates: ") 

    var inputs [][]float64 

    scanner := bufio.NewScanner(os.Stdin) 
    for scanner.Scan() { 
     if len(scanner.Text()) > 0 { 
      raw_input := strings.Replace(scanner.Text(), " ", "", -1) 
      input := strings.Split(raw_input, ",") 
      converted_input := str2float(input) 
      inputs = append(inputs, converted_input) 
     } else { 
      break 
     } 
    } 

    return inputs 
} 

func str2float(records []string) []float64 { 

    var float_slice []float64 

    for _, v := range records { 
     if s, err := strconv.ParseFloat(v, 64); err == nil { 
      float_slice = append(float_slice, s) 
     } 
    } 

    return float_slice 
} 
+0

Cela me semble bon. Golang peut être moins verbeux que le C simple, mais presque rien ne bat Python pour le code concis ... En passant, il devrait être plus long: vous devriez vérifier scanner.Err() après la boucle for. –

+0

@StephaneMartin, merci beaucoup pour votre commentaire. Je viens de vérifier la documentation de Golang sur Scanner. Voulez-vous dire la ligne 'si err: = scanner.Err(); err! = nil ... 'devrait être ajouté pour détecter une erreur? – Nahua

+0

oui, après le retour de la boucle, pour vérifier que le scanner pourrait effectivement analyser le contenu –

Répondre

2

En utilisant uniquement les fonctions de chaîne:

package main 

import (
    "bufio" 
    "fmt" 
    "os" 
    "strconv" 
    "strings" 
) 

func main() { 
    scanner := bufio.NewScanner(os.Stdin) 
    var result [][]float64 
    var txt string 
    for scanner.Scan() { 
     txt = scanner.Text() 
     if len(txt) > 0 { 
      values := strings.Split(txt, ",") 
      var row []float64 
      for _, v := range values { 
       fl, err := strconv.ParseFloat(strings.Trim(v, " "), 64) 
       if err != nil { 
        panic(fmt.Sprintf("Incorrect value for float64 '%v'", v)) 
       } 
       row = append(row, fl) 
      } 
      result = append(result, row) 
     } 
    } 
    fmt.Printf("Result: %v\n", result) 
} 

Run:

$ printf "1.1,2.2,3.3 
3.14,0,5.16 
2,45,76.0, 45 , 69" | go run experiment2.go 

Result: [[1.1 2.2 3.3] [3.14 0 5.16] [2 45 76 45 69]] 
+0

Bonjour Eugene, merci de partager votre solution! Vraiment comme votre idée d'écrire toutes les données d'entrée en ligne de commande :) – Nahua

1

Avec entrée donné, vous pouvez les concaténer pour faire une chaîne JSON puis unmarshal (deserialize) que:

func main() { 
    var lines []string 
    for { 
     var line string 
     fmt.Scanln(&line) 
     if line == "" { 
      break 
     } 
     lines = append(lines, "["+line+"]") 
    } 
    all := "[" + strings.Join(lines, ",") + "]" 
    inputs := [][]float64{} 
    if err := json.Unmarshal([]byte(all), &inputs); err != nil { 
     fmt.Println(err) 
     return 
    } 

    fmt.Println(inputs) 
} 
+0

Merci Kaveh. Je n'ai jamais utilisé JSON avec Go et j'y regarderai! – Nahua