0

I am trying to figure out why my code is not working. I wish to take a slice of numbers and strings, and separate it into three slices. For each element in the slice, if it is a string, append it to the strings slice, and if it is a positive number, append it to the positive numbers, and likewise with negative. Yet, here is the output

Names: EvTremblay 45.39934611083154 -75.71148292845268

[Crestview -75.73795670904249 BellevueManor -75.73886856878032 Dutchie'sHole -75.66809864107668 ...

Positives:[45.344387632924054 45.37223315413918 ... ] Negatives: []

Here is my code. Can someone tell me what is causing the Negatives array to not have any values?

func main() {
    fmt.Printf("%q\n", strings.Split("a,b,c", ","))
    var names []string
    var positives, negatives []float64
    bs, err := ioutil.ReadFile("poolss.txt")
    if err != nil {
        return
    }
    str := string(bs)
    fmt.Println(str)
    tokens := strings.Split(str, ",")
    for _, token := range tokens {
        if num, err := strconv.ParseFloat(token, 64); err == nil {
            if num > 0 {
                positives = append(positives, num)
            } else {
                negatives = append(negatives, num)
            }

        } else {
            names = append(names, token)
        }

    fmt.Println(token)
    }

    fmt.Println(fmt.Sprintf("Strings: %v",names))
    fmt.Println(fmt.Sprintf("Positives: %v", positives))
    fmt.Println(fmt.Sprintf("Negatives: %v",negatives))
    for i := range names{
        fmt.Println(names[i])

        fmt.Println(positives[i])

        fmt.Println(negatives[i])
    }
}
user3015224
  • 27
  • 2
  • 5
  • Looks like your input isn't strictly comma separated. Also, the last loop assumes that all slices have the same length, which seems unlikely. – Peter Apr 15 '18 at 15:07
  • Here is my input: Crestview,45.344387632924054,-75.73795670904249 BellevueManor,45.37223315413918,-75.73886856878032 Dutchie'sHole,45.420784695340274,-75.66809864107668 Bingham,45.43364510779131,-75.69570714265845 AlvinHeights,45.45147956435529,-75.65100870365318 Britannia,45.36063791083469,-75.79935158132524 Chaudiere,45.40984992554796,-75.71353870063207 Parkdale,45.40138661908912,-75.73023035094172 AltaVista,45.383081724040146,-75.6663971454287 CecilMorrison,45.417175891787146,-75.64599611564647 – user3015224 Apr 15 '18 at 15:21
  • See? There are newlines in there. – Peter Apr 15 '18 at 15:35

3 Answers3

2

Your code has strings as a variable name:

var strings []string

and strings as a package name:

tokens := strings.Split(str, ",")

Don't do that!

strings.Split undefined (type []string has no field or method Split)

Playground: https://play.golang.org/p/HfZGj0jOT-P

peterSO
  • 158,998
  • 31
  • 281
  • 276
1

Your problem above I think lies with the extra \n attached to each float probably - you get no negative entries if you end in a linefeed or you would get one if you have no linefeed at the end. So insert a printf so that you can see the errors you're getting from strconv.ParseFloat and all will become clear.

Some small points which may help:

  • Check errors, and don't depend on an error to be of only one type (this is what is confusing you here) - always print the error if it arrives, particularly when debugging
  • Don't use the name of a package for a variable (strings), it won't end well
  • Use a datastructure which reflects your data
  • Use the CSV package to read CSV data

So for example for storing the data you might want:

type Place struct {
   Name string 
   Latitude int64
   Longitude int64
}

Then read the data into that, depending on the fact that cols are in a given order, and store it in a []Place.

Kenny Grant
  • 9,360
  • 2
  • 33
  • 47
  • I do have a struct like that. However, I figured I would read into 3 separate arrays, then use one iterator to read from each of the arrays and assign structs from that so I could just go for i, v := range names{ p := make(Place) p.Name = v p.Latitude = positives[i] p.Longitude = negatives[i] } then append that to a slice – user3015224 Apr 15 '18 at 16:13
  • I think you'd be better to use the csv library, and read each row into a struct, either would work I guess, but you should consider each row alone really - your problem arose because you code assumes failure to parse float meant 'new row' when there can be other causes. – Kenny Grant Apr 15 '18 at 18:33
0

Here's what I tried, it works now! Thanks for the help, everyone!

func main() {
findRoute("poolss.csv", 5)
 }

func findRoute( filename string, num int) []Edge {
var route []Edge
csvFile, err := os.Open(filename)
if err != nil {
    return route
}
reader := csv.NewReader(bufio.NewReader(csvFile))
var pools []Pool
for {
    line, error := reader.Read()
    if error == io.EOF {
        break
    } else if error != nil {
        log.Fatal(error)
    }
    lat, err := strconv.ParseFloat(line[1], 64)
    long, err := strconv.ParseFloat(line[2], 64)
    if err == nil {
        pools = append(pools, Pool{
            name: line[0],
            latitude:  lat,
            longitude: long,
        })
    }
}
return route
}
user3015224
  • 27
  • 2
  • 5