3 Replies
      Latest reply: Oct 25, 2016 4:13 AM by eskimo RSS
      Alexandre Carmo Level 1 Level 1 (0 points)

        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?

        • Re: NSArray filtered type
          goldsdad Level 4 Level 4 (580 points)

          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).

          • Re: NSArray filtered type
            ahltorp Level 3 Level 3 (410 points)

            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.

              • Re: NSArray filtered type
                eskimo Apple Staff Apple Staff (7,530 points)

                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"