The type signature of Array's filter instance method is
func filter(includeElement: (T) -> Bool) -> [T]
Which means that it takes a function that takes an argument of type T and returns true or false and the filter instance methods returns an array of type T which is the same type as the function's parameter given to it.
Your first use of filter works because it's an array of String data types though the second doesn't work because (song: String, id: String) implies that there's a function with two parameters given to filter. The error generated by compiler fully describes it. It says the type is a dictionary thus [String : String]. So, in order to make it work you should do it in this way:
Remember that Dictionary data type has an instance variable called keys which returns a value of type LazyForwardCollection<MapCollectionView<[Key : Value], Key>>. The definition is
var keys: LazyForwardCollection<MapCollectionView<[Key : Value], Key>> { get }
LazyForwardCollection has an instance variable first which gives you the first element, it also has array which gives you all the elements.
var first: S.Generator.Element? { get }
// Let the compiler infer the type though you can give (dict: [String : String]) -> Bool
masterFilter = master.filter { dict in
let song = dict.keys.first
let stringMatch = song.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
return stringMatch != nil
}
I didn't use for-in loop because the way your code showed(though it didn't compile) me, it just has one key/value pair in dictionaries inside the array. Although you can use it if there's a need.
You also didn't use id. So it seems to me that you don't need the values, though the nature of dictionary is that you need both keys and values otherwise Array data type would work. One possible guess is that you're retrieving the data from a web server that returns a JSON or other notations so you first cast it to dictionary then use it.