1

I have a chat filled with users and of course a username array. I want to get the profile picture associated with the username in order for each user in the username array. Parse, however, can only sort by ascending/descending order that I am aware of.

Therefore, I need to figure out how to sort the data once received. I am ultimately appending a url to be used as the pic.

    func getPics(_ completionHandler: @escaping () -> Void) {
    let query = PFQuery(className: "_User")
    
    var dictionary: [String : Int] = [:]
    var unit = 0
    for username in usernameArray {
        unit += 1
        dictionary[username] = unit
    }
    query.findObjectsInBackground(block: { (objects: [PFObject]?, error: Error?) in
    if let objects = objects {
        for object in objects {
                if error == nil {
                    for user in self.usernameArray {
                    let pfuser = object["username"] as! String
                    if pfuser == user {
                    let imageFile = object["profilePic"] as? PFFileObject
                    let imageFileString = imageFile?.url as! String
                    if let url = URL(string: imageFileString) {
                        let replacedImageUrlString = imageFileString.replacingOccurrences(of: "[removed for privacy]", with: "removed for privacy")
                        let url = replacedImageUrlString as NSString
                        self.urlArray.append(url)
                        }
                                }
                            }
                        }
        }
                     completionHandler()
                }
            })
    }
WhySoSerious33
  • 81
  • 1
  • 1
  • 4

1 Answers1

0

I am not aware of Parse server, So I dont really know if there exists provision to get the response in specific order, if it exists that should be the optimal solution. But there is a generic issue with your solution, its the time complexity. You have two nested for loops which makes its worst case complexity to be O(n^2), I guess the least you can do is to reduce its complexity to O(n)

func getPics(_ completionHandler: @escaping () -> Void) {
    let query = PFQuery(className: "_User")

    var dictionary: [String : Int] = [:]
    var unit = 0
    for username in usernameArray {
        unit += 1
        dictionary[username] = unit
    }
    query.findObjectsInBackground(block: { (objects: [PFObject]?, error: Error?) in
        if let objects = objects, error == nil {
            let objectsDict = Dictionary(grouping: objects, by: { $0["username"] as! String /* typically you should be accessing $0.username, but again am not aware of  PFObject */})
            for user in self.usernameArray {
                if let pfuser = objectsDict[user]?[safe: 0] as? PFObject {
                    let imageFile = pfuser["profilePic"] as? PFFileObject
                    let imageFileString = imageFile?.url as! String
                    if let url = URL(string: imageFileString) {
                        let replacedImageUrlString = imageFileString.replacingOccurrences(of: "[removed for privacy]", with: "removed for privacy")
                        let url = replacedImageUrlString as NSString
                        self.urlArray.append(url)
                    }
                }
            }
            completionHandler()
        }
    })
}

Once you get the array of PFObject, you can create a dictionary with username as the key and PFObject as value, once you have the dictionary you can get the PFObject for specific username in O(1), so you can run a single for loop which reduces your code's complexity to O(n)

P.S If you are wondering what [safe: 0] is you can add this handy extension to safely access object at specific index in an array

link: Safe (bounds-checked) array lookup in Swift, through optional bindings?

extension Collection {
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

P.P.S: My answer is completely ignoring the complexity of Dictionary(grouping: API itself, I tried to look for the info, but couldnt find. But I think its O(n) not really sure though, whatever it is if its not O(n^2) you will still be benefited

Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78