简体   繁体   中英

Filter an object on a nested array in Realm Swift

I have the main model of ChatConversationModel , which has an array property userAcitivities that is an array of ChatUserAcitivityModel objects. I want to get from Realm the ChatConversationModel object in which the userAcitivities contains the given friendID . I've tried a few different ways but haven't been able to get the result I'm after.

import Foundation
import RealmSwift
import ObjectMapper

class ChatConversationModel: Object, Mappable {

    dynamic var id = ""
    dynamic var typeIndex = ChatTypes.ChatType.oneToOne.index
    var userAcitivities = List<ChatUserAcitivityModel>()

    override class func primaryKey() -> String? {
        return "id"
    }

    convenience required init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
        if map.mappingType == .fromJSON {
            id <- map["id"]
            typeIndex <- map["typeIndex"]
            userAcitivities <- (map["userAcitivities"], ListTransform<ChatUserAcitivityModel>())
        } else {
            id >>> map["id"]
            typeIndex >>> map["typeIndex"]
            userAcitivities >>> (map["userAcitivities"], ListTransform<ChatUserAcitivityModel>())
        }
    }

}

import Foundation
import RealmSwift
import ObjectMapper

class ChatUserAcitivityModel: Object, Mappable {

    dynamic var userID = ""
    /// This is necessary in order to know from what point to download the chat if the user deleted it.
    /// If this property is 0.0, then there has never been a deletion.
    dynamic var removedChatTimeStamp = 0.0

    override class func primaryKey() -> String? {
        return "userID"
    }

    convenience required init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
        if map.mappingType == .fromJSON {
            userID <- map["userID"]
            removedChatTimeStamp <- map["removedChatTimeStamp"]
        } else {
            userID >>> map["userID"]
            removedChatTimeStamp >>> map["removedChatTimeStamp"]
        }
    }

}

func getFriendChatConversationModel(_ friendID: String)  {
    let realm = try! Realm()
    let chatConversationModels = realm.objects(ChatConversationModel.self).filter("typeIndex = %@", ChatTypes.ChatType.oneToOne.index)
    let friend = chatConversationModels.filter { $0.userAcitivities.filter { $0.userID == friendID } }
}

At the moment I'm doing the following and it's working for me, but I'd like to find the best way to express this:

 func getFriendChatConversationModel(_ friendID: String) -> ChatConversationModel? {
    let realm = try! Realm()
    let chatConversationModels = realm.objects(ChatConversationModel.self).filter("typeIndex = %@", ChatTypes.ChatType.oneToOne.index)

    var friendChatConversationModel: ChatConversationModel?

    for chatConversationModel in chatConversationModels {
        if chatConversationModel.userAcitivities.contains(where: { (chatUserAcitivityModel) -> Bool in
            chatUserAcitivityModel.userID == friendID
        }) {
            friendChatConversationModel = chatConversationModel
            return friendChatConversationModel
        }
    }
    return nil
}

If I understand correctly, I think a query like this will do what you're after:

func getFriendChatConversationModel(_ friendID: String) -> ChatConversationModel? {
    let realm = try! Realm()
    let chatConversationModels = realm.objects(ChatConversationModel.self).filter("typeIndex = %@", ChatTypes.ChatType.oneToOne.index)
    return chatConversationModels.filter("ANY userAcitivities.userID == %@", friendID).first
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM