NSArray filtered type

I create a code on swift 2, this is the code:


...
var data = []
var filtered = []
...
func myFunc(text: String) {
        let resultPredicate = NSPredicate(format: "name_friend contains[c] %@", text)
        self.filtered = self.data.filteredArrayUsingPredicate(resultPredicate)
     ...
    }


I rewrite on swift 3, this is the code:

...
var data:[[String:Any]] = []
var filtered:[[String:Any]] = []
...

func myFunc(text: String) {
        let resultPredicate = NSPredicate(format: "name_friend contains[c] %@", text)
        self.filtered = self.data.filtered(using: resultPredicate)
       ...
    }


But on swift 3 code I receive this message error on self.data.filtered:


Value of type [[String:Any]] has no member 'filtered'


So if the array [[String:Any]] dont have'filtered', whats the way to use the similiar type?

Accepted Reply

If you still want to use NSPredicate, you will have to cast it to NSArray and cast the result back again.


self.filtered = (self.data as NSArray).filtered(using: resultPredicate) as! [[String:Any]]


If you are using this in many places, you could extend Array to have the .filtered(predicate:) method:


extension Array {
    func filtered(using predicate: NSPredicate) -> Array {
        return (self as NSArray).filtered(using: predicate) as! Array
    }
}


If you have no particular reason to use NSPredicate, you are probably better off using .filter(_:) as goldsdad suggested.

Replies

NSArray has filtered(using:) method, but your Swift 3 code is explicitly declaring data to be a Swift Array, which has a filter(_:) method (and that takes a closure, not a NSPredicate, so see API reference for Array).

If you still want to use NSPredicate, you will have to cast it to NSArray and cast the result back again.


self.filtered = (self.data as NSArray).filtered(using: resultPredicate) as! [[String:Any]]


If you are using this in many places, you could extend Array to have the .filtered(predicate:) method:


extension Array {
    func filtered(using predicate: NSPredicate) -> Array {
        return (self as NSArray).filtered(using: predicate) as! Array
    }
}


If you have no particular reason to use NSPredicate, you are probably better off using .filter(_:) as goldsdad suggested.

If you have no particular reason to use NSPredicate, you are probably better off using

.filter(_:)
as goldsdad suggested.

Agreed. For example:

filtered = data.filter { element in
    return (element["name_friend"] as? String)?.range(of: text, options: [.caseInsensitive]) != nil
}

ps This code would be a lot nicer if you replaced the elements of the array with a model object rather than a dictionary. Most of the goo in the snippet above is related to extracting the

name_friend
‘field’ from the dictionary. If this were a struct, the code would be much simpler:
filtered = data.filter { element in
    return element.nameFriend.range(of: text, options: [.caseInsensitive]) != nil
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"