Reputation: 1446
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
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
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