使用 Parse Server 在 Swift 循环中迭代 For
Iterating For In Loop In Swift Using Parse Server
我有一个充满用户的聊天室,当然还有一个用户名数组。我想获取与用户名关联的个人资料图片,以便为用户名数组中的每个用户排序。但是,Parse 只能按我知道的 ascending/descending 顺序排序。
因此,我需要弄清楚接收到的数据如何排序。
我最终会附加一个 url 用作图片。
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()
}
})
}
我不知道 Parse 服务器,所以我真的不知道是否存在以特定顺序获取响应的规定,如果存在那应该是最佳解决方案。但是您的解决方案存在一个普遍问题,即 时间复杂度 。
你有两个嵌套的 for 循环,这使得它的 worst case complexity 成为 O(n^2),我想你至少可以做的是将其复杂度降低到 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: { [=10=]["username"] as! String /* typically you should be accessing [=10=].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()
}
})
}
一旦你得到PFObject
的数组,你就可以创建一个以用户名为键,PFObject为值的字典,一旦你有了字典,你就可以得到特定用户名的PFObject
O(1),因此您可以 运行 一个 for 循环,将代码的复杂性降低到 O(n)
P.S 如果您想知道 [safe: 0]
是什么,您可以添加这个方便的扩展以安全地访问数组中特定索引处的对象
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: 我的回答完全忽略了 Dictionary(grouping:
API 本身的复杂性,我试图寻找信息, 但找不到。但我认为它 O(n) 不太确定,不管它是什么,如果它不是 O(n^2) 你仍然会受益
我有一个充满用户的聊天室,当然还有一个用户名数组。我想获取与用户名关联的个人资料图片,以便为用户名数组中的每个用户排序。但是,Parse 只能按我知道的 ascending/descending 顺序排序。
因此,我需要弄清楚接收到的数据如何排序。 我最终会附加一个 url 用作图片。
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()
}
})
}
我不知道 Parse 服务器,所以我真的不知道是否存在以特定顺序获取响应的规定,如果存在那应该是最佳解决方案。但是您的解决方案存在一个普遍问题,即 时间复杂度 。 你有两个嵌套的 for 循环,这使得它的 worst case complexity 成为 O(n^2),我想你至少可以做的是将其复杂度降低到 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: { [=10=]["username"] as! String /* typically you should be accessing [=10=].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()
}
})
}
一旦你得到PFObject
的数组,你就可以创建一个以用户名为键,PFObject为值的字典,一旦你有了字典,你就可以得到特定用户名的PFObject
O(1),因此您可以 运行 一个 for 循环,将代码的复杂性降低到 O(n)
P.S 如果您想知道 [safe: 0]
是什么,您可以添加这个方便的扩展以安全地访问数组中特定索引处的对象
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: 我的回答完全忽略了 Dictionary(grouping:
API 本身的复杂性,我试图寻找信息, 但找不到。但我认为它 O(n) 不太确定,不管它是什么,如果它不是 O(n^2) 你仍然会受益