buildmaestro
buildmaestro

Reputation: 1446

float64 to string without [] in result

I'm trying to scan some folders and sort them to find the highest version number. {"10.1","9.6","7.2"} and then build a path. However, What I get has [] brackets in the path and I need to get rid of those.

Here's what I'm getting:

C:\Program Files\PostgreSQL\[10.1]\bin\psql.exe

        root := "C:/Program Files/PostgreSQL"


        files, err := ioutil.ReadDir(root)
        if err != nil {
            return "", err
        }

        folders := []float64{}
        for _, f := range files {
            if f.IsDir() {
                if converted, err := strconv.ParseFloat(f.Name(),64); err == nil {
                    folders = append(folders, converted)
                }
            }
        }

        sort.Float64s(folders)

        log.Println(folders[len(folders)-1:])

        highestVersion := fmt.Sprintf("%v",folders[len(folders)-1:])

        execPath = filepath.Join(root, highestVersion, "bin", "psql.exe") 
        log.Println(execPath)

Upvotes: 0

Views: 116

Answers (2)

adam_0
adam_0

Reputation: 7200

The issues are on this line:

highestVersion := fmt.Sprintf("%v",folders[len(folders)-1:])

The %v format specifier, as some people have mentioned, is shorthand for "value". Now let's look at your value:

folders[len(folders)-1:]

What you are saying here is, "take a slice from folders starting at len(folders-1)". Your variable is a slice that only contains the last item in folders.

Slices are printed by using brackets around the values, and since you have one value, it prints the value surrounded by square brackets.

If you want to print just the float contained in that location, you should remove the colon as specified in a comment. I would recommend printing using the fmt verb %f or %g, depending on your use case.

More information can be found in the pkg/fmt docs about what verbs are available to printf and other related functions.

Upvotes: 1

maerics
maerics

Reputation: 156464

One possible approach would be to use a regular expression to ensure that each path has the expected format and to extract the version number as a float via a submatch (matching group), then sort the path strings by their floating point version number value and return the highest one.

For example:

func main() {
  paths := []string{
    `C:\Program Files\PostgreSQL\[1.2]\bin\psql.exe`,
    `C:\Program Files\PostgreSQL\[9.6]\bin\psql.exe`,
    `C:\Program Files\PostgreSQL\[10.1]\bin\psql.exe`,
    `C:\Program Files\PostgreSQL\[7.2]\bin\psql.exe`,
  }

  sort.Slice(paths, func(i, j int) bool {
    return parseVersion(paths[i]) >= parseVersion(paths[j])
  })
  fmt.Printf("OK: highest version path = %s\n", paths[0])
  // OK: highest version path = C:\Program Files\PostgreSQL\[10.1]\bin\psql.exe
}

var re = regexp.MustCompile(`C:\\Program Files\\PostgreSQL\\\[(\d+\.\d+)\]\\bin\\psql.exe`)

func parseVersion(s string) float32 {
  match := re.FindStringSubmatch(s)
  if match == nil {
    panic(fmt.Errorf("invalid path %q", s))
  }
  version, err := strconv.ParseFloat(match[1], 32)
  if err != nil {
    panic(err)
  }
  return float32(version)
}

Of course, you could modify the path regular expression to match different location patterns if that matters for your use case.

Upvotes: 1

Related Questions