【问题标题】:Parse PFQuery - Check if arrays are identical - SwiftParse PFQuery - 检查数组是否相同 - Swift
【发布时间】:2017-11-22 21:21:36
【问题描述】:

我正在尝试在 xcode 中构造一个解析查询,该查询采用通过前一个 segue 传递给视图控制器的对象数组,从这些对象创建一个 objectId 数组,并查询数组 objectId 中的完全匹配“MessageThread”类中的键“参与者”中的值

我一直在阅读解析文档,我能想到的最佳查询是 containsAllObjectsIn:

显然, containsAllObjectsIn 在某些情况下会起作用。但是,该查询仅检查键“参与者”中是否存在所有 objectId。它不检查数组是否相同。因此,查询将返回对象,虽然它们确实包含所有 objectId,但可能包含额外的 objectId。

为了抵消这种负面影响,我对每个返回的对象进行检查,以查看返回对象中的 objectIds 是否与原始数组相同。我在下面包含了视图控制器代码。

虽然我目前在下面解决的代码似乎在测试后按预期工作,但我不禁知道必须有一种更有效的方法来通过 PFQuery 检查数组是否相同。

关于如何使这段代码更好的任何想法或帮助?谢谢。

import UIKit
import Parse

class MessageThreadViewController: UIViewController {

@IBOutlet weak var sendNewMessageButton: UIButton!

var participantsList:[PFObject] = []
var participantsListIds:[String] = []
var currentMessageThreadObject:PFObject?
var threadMessages:[PFObject] = []

override func viewDidLoad() {
    super.viewDidLoad()
    initialViewSetup()
    checkForExistingMessageThread()
}

func initialViewSetup() {
    sendNewMessageButton.isEnabled = false
    for participant in participantsList {
        participantsListIds.append(participant.objectId!)
    }
}

func checkForExistingMessageThread () {
    print("-------------------")
    print(participantsListIds)
    let query = PFQuery(className: "MessageThread")
    query.whereKey("participants", containsAllObjectsIn: participantsList)
    query.includeKey("messages")
    query.findObjectsInBackground(block: { (threads, error) in
        if error != nil {
            if let error = error {
                print(error)
            }
        } else {
            if let threads = threads {
                if threads.isEmpty {
                    print("no thread found. creating thread....")
                    self.createMessageThread()
                } else {
                    print("existing thread match(es) found")
                    var activeThreadFound = false
                    for thread in threads {
                        let returnedThreadParticipants = thread["participants"] as! [PFObject]
                        var returnedThreadParticipantsIds:[String] = []
                        for participant in returnedThreadParticipants {
                            returnedThreadParticipantsIds.append(participant.objectId!)
                        }
                        if returnedThreadParticipantsIds.containsSameElements(as: self.participantsListIds) {
                            activeThreadFound = true
                            print("thread identical match found")
                            self.currentMessageThreadObject = thread
                            self.sendNewMessageButton.isEnabled = true
                            if let queriedThreadMessages = thread["messages"] {
                                let queriedThreadMessagesAsObjects = queriedThreadMessages as! [PFObject]
                                self.threadMessages = queriedThreadMessagesAsObjects
                                self.messagesTableView.reloadData()
                                self.sendNewMessageButton.isEnabled = true
                            }
                            break
                        } else {

                            print("non-identical thread found")
                        }
                    }
                    if activeThreadFound == false {
                        print("matches were found, but no identical thread. Creating thread....")
                        self.createMessageThread()
                    }
                }
            }
        }
    })
}

func createMessageThread() {
    let newMessageThread = PFObject(className:"MessageThread")
    newMessageThread["participants"] = participantsList
    newMessageThread.saveInBackground(block: { (success, error) in
        if error != nil {
            if let error = error {
                print(error)
            }
        } else {
            self.checkForExistingMessageThread()
        }
    })

}

}

extension Array where Element: Comparable {
func containsSameElements(as other: [Element]) -> Bool {
    return self.count == other.count && self.sorted() == other.sorted()

}

【问题讨论】:

    标签: swift parse-platform


    【解决方案1】:

    你可以这样试试:

    query.whereKey("participants", equalTo: [
        "$eq" : participantsList
    ])
    

    【讨论】:

    • 嗨,戴维,感谢您的建议。我试了一下您的查询,收到以下错误:“*** 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'无法对类型进行比较查询:TtGCs26_SwiftDeferredNSDictionarySSGSaCSo6PFUser_'”跨度>
    • 看起来我需要与一组用户 ID 进行比较?如果两个比较数组元素的排列顺序不同,会有关系吗?
    • 嗯......他们唯一的问题是“参与者”是一个指向用户对象的指针数组。
    • 我在 API 中进行了测试,它运行良好,但它没有通过 SDK 验证。我认为您将能够从云代码中做到这一点。但首先,我将在单独的回复中发送另一个建议。如果它也不起作用,我可以从云代码中弄清楚如何做到这一点。
    【解决方案2】:

    我的另一个建议是尝试在同一个查询中组合 containsIn 和 containsAllObjectsInArray。请尝试以下方法:

    let query = PFQuery(className: "MessageThread")
    query.whereKey("participants", containsAllObjectsInArray: participantsList)
    query.whereKey("participants", containedIn: participantsList)
    

    【讨论】:

    • 刚刚试了一下这段代码,看来这个查询仍然能够匹配多个“MessageThread”。不幸的是,这与看起来的初始查询行为相同。无赖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多