0

I'm trying to get code from github for auto-completion to work, but am stuck with an error on line 6 (data.filter) that Dictionary does not have a member named filter. But everything I read in the documentation suggests dictionaries should have a filter method. I've tried every possible combination of unwrapping, self, etc, but the compiler then registers these changes as the error.

Obviously something is going on that I do not understand - any guidance is appreciated.

var data = Dictionary<String, AnyObject>()    
func applyFilterWithSearchQuery(filter : String) -> Dictionary<String, AnyObject>
{
    var lower = (filter as NSString).lowercaseString
    if (data.count > 0) {
        var filteredData = data.filter ({
            if let match : AnyObject  = $0["DisplayText"]{
                return (match as NSString).lowercaseString.hasPrefix((filter as NSString).lowercaseString)
            }
            else{
                return false
            }
        })
    }
    return filteredData
}
DrWhat
  • 2,360
  • 5
  • 19
  • 33
  • The swift project from this repo is full of errors and I don't think it is finished: not the best example if you don't want to spend some time to fix it as a learning practice. The `filter` property must've been left as the author tried to refactor the code and replace `NSArray` (which used `filteredArrayUsingPredicate` method) with `Dictionary`. – A-Live Nov 11 '14 at 11:43
  • @A-Live - thank you very much for this assessment of MPGTextField. I'll focus on the learning, and look elsewhere for an implementation. Thanks for saving me a lot of head-against-the-wall-banging. – DrWhat Nov 12 '14 at 08:04
  • @A-Live - thank you very much for this assessment of MPGTextField. I'll focus on the learning, and look elsewhere for an implementation. Thanks for saving me a lot of head-against-the-wall-banging. The 2010 Ray Wenderlich Obj-C example looks simple, but I'm struggling to get it running in Swift - [here is another thread on this approach](http://stackoverflow.com/questions/26885438/getting-autocomplete-to-work-in-swift). – DrWhat Nov 12 '14 at 11:10

2 Answers2

1

Never heard of dictionary filters - where have you read about that? Arrays do have a filter method, but not dictionaries. What you can do is filter keys or values (accessible via the respective dictionary properties).

You can implement a custom filter on a dictionary with the following code:

var filtered = dict.keys.filter { $0.hasPrefix("t") }.map { (key: $0, value: dict[$0]) }

var newDict = [String : AnyObject]()
for element in filtered {
    newDict[element.key] = element.value
}

which filter keys, then maps each key to a (key, value) tuple, then add each tuple to a new dictionary.

Note that to filter keys I used hasPrefix("t") - replace that with something more appropriate to your case

Antonio
  • 71,651
  • 11
  • 148
  • 165
0
var data = Dictionary<String, AnyObject>()

func applyFilterWithSearchQuery(filter: String) -> [String : AnyObject] {
        var lower = filter.lowercaseString

        var filteredData = [String : AnyObject]()

        if (!data.isEmpty) {
                Swift.filter(data) {
                        (key, value) -> Bool in

                        if key == "DisplayText" {
                                filteredData[key] = (value as? String)?.lowercaseString.hasPrefix(lower)
                        }

                        return false
                }

                /* use map function works too
                map(data) {
                        (key, value) -> Void in

                        if key == "DisplayText" {
                                filteredData[key] = (value as? String)?.lowercaseString.hasPrefix(lower)
                        }
                }
                */
        }

        return filteredData
}
linimin
  • 6,239
  • 2
  • 26
  • 31
  • This compiles, If understood(!), I'm converting my string to lower case, creating an empty dictionary filteredData, and if the data dictionary is not empty, I'll look there for a key matching the display text and then add the key and value to filteredData and return false. If data was empty, I'd return the filteredData dictionary. BUT, wouldn't the filtedData dictionary be empty? AND, what is the keyword Swift doing in the line Swift.filter(data)? – DrWhat Nov 11 '14 at 19:18
  • If you don't want the function to return an empty dictionary when `data` is empty, change the return type of the function to `[String : AnyObject]?` and return `nil` when `data` is empty. `filter(data)` is prefixed with `Swift` to avoid a name conflict with the parameter name of the function, which is also called `filter`. You can remove it after changing the parameter name. – linimin Nov 12 '14 at 02:08