Check if filepath.Ext(path) is in an array that contains extensions

Hi guys,

I’m new to Go and started to learn it yesterday. I have some programming experience so it was pretty easy to pick up. Everything was pretty good until I’ve hit this wall.

Basically, I’m doing a little program for fun (and for learning) that loops through files using filepath.Walk and I want it to append the files to fileList only if they have a specific extension.

var fileList []string       
var extensions = []string{".exe", ".dll", ".sys"}

	filepath.Walk(dir, func(path string, f os.FileInfo, err error) error {
		if filepath.Ext(path) := range extensions {
			fileList = append(fileList, path)
			} 
		}
		return nil

The issue I encounter is when it reaches if filepath.Ext(path) := range extensions, this part doesn’t work. But it I do if filepath.Ext(path) == ".exe" || filepath.Ext(path) == ".dll" || filepath.Ext(path) == ".sys" it works fine. But I don’t think it looks nice and if there is something I don’t understand dealing with arrays and slices, I need to know what it is.

By the way I also have no idea of how filepath.Walk() works, took a snippet from a site so if someone wants to explain I’d appreciate it too. Seems similar to os.walk() in Python but clearly isn’t working the same way.

Thanks :slight_smile:

edit: phrasing

Go doesn’t have a builtin for checking if an element is in a list, like the in operator in Python. Instead, you do it manually by looping over it, or you use a map, or you use a sorted slice and sort.Search.

func stringInSlice(v string, ss []string) bool {
    for _, s := range ss {
        if s == v {
            return true
        }
    }
    return false
}

exts := []string{".exe", ".dll", ".sys"}

if stringInSlice(filepath.Ext(path), exts) {
    // it's an executable
}
exts := map[string]bool {
    ".exe": true,
    ".dll": true,
    ".sys": true,
}

if exts[filepath.Ext(path)] {
    // it's an executable
}

(People will quibble you should use a map[string]struct{} instead. Ignore them until you understand what that is and why it might be better.)

func stringInSortedSlice(v string, ss []string) bool {
    i := sort.Search(len(ss), func(i int) bool { return ss[i] >= v })
    return i < len(ss) && ss[i] == v
}

exts := []string{".dll", ".exe", ".sys"} // n.b. sorted

if stringInSortedSlice(filepath.Ext(path), exts) {
    // it's an executable
}

filepath.Walk will call the function you give it, for every path it finds.

5 Likes

Hey thanks a lot!

Makes more sense now. I was struggling to understand why none of my attempts were working. I’ll try that out!

As for map[string]struct{} you’re right that doesn’t mean anything to me for the moment but I found this blog post about it: https://blog.golang.org/go-maps-in-action so I’ll give it a read later.

Thanks again!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.