检查Realm列表属性是否包含另一个列表的所有元素

问题描述 投票:0回答:1

我正在使用iOS / Swift和Realm,我有几个像这样定义的Realm模型:

class Message: Object {

    // other properties removed for brevity

    var recipients = List<User>()
    var acknowledgedBy = List<User>()

    @objc dynamic var fullyAcknowledged = false
}

class User: Object {

    @objc dynamic var id: Int = -1
    @objc dynamic var name: String = ""

    convenience init(id: Int, name: String) {
        self.init()        
        self.id = id
        self.name = name
    }
}

我的消息对象有一个recipients属性,该属性将包含此消息应发送到的用户列表。当用户收到消息时,他们会确认消息,然后该用户将被添加到消息的acknowledgedBy列表中。每次将用户添加到acknowledgedBy列表时,我都需要检查是否应该收到该消息的每个人都已确认该消息。满足该条件时,我将消息的fullyAcknowledged属性设置为true。

要检查消息是否已被所有人确认,我知道我可以遍历recipients中的每个用户,然后检查该用户是否也在acknowledgedBy列表中。我还认为我可以通过以下两步过程实现这一目标:

  1. 比较recipientsacknowledgedBy中的元素数量,以确保它们是相同的;如果它们是...
  2. 对两个列表进行排序,然后比较它们以确定它们是否包含相同的用户

但我想知道是否有更有效的方法来确定一个列表包含另一个列表的所有元素(即使它们的顺序不同)?

编辑----------

看起来我也可以使用Sets来做出这样的决定:

let ackSet = Set(message.acknowledgedBy)
let recipientSet = Set(message.recipients)
let fullyAcknowledged = ackSet.isSubset(of: recipientSet)
ios swift realm
1个回答
0
投票

套装不是一个很好的选择我认为,想象你在其中一个列表中有重复,那么这是错误的选择。我强烈建议你去看看Testing for equality in Realm

如果User是唯一的,我会使用primaryKey https://realm.io/docs/swift/latest/#primary-keys。然后当你用相同的id保存你的对象时,不会创建副本=>你可以比较这个对象==默认的领域实现

如果两个不同的用户可以拥有相同的ID,那么我将编写自己的方法,该方法需要id和name相等。然后,您可以使用[String: Int]创建字典,以便您可以使用以下代码

var dict = [String: Int]()
message.acknowledgedBy.forEach { user in
  if let value = dict[user.name + "\(id)"] {
    dict[user.name + "\(id)"] = value + 1        
  } else {
    dict[user.name + "\(id)"] = 1
  }
}
let isMatched = message.recipients.reduce(true) { (reducedValue, user) in
  if let value = dict[user.name + "\(id)"] {
     dict[user.name + "\(id)"] = value - 1
     return (value - 1 >= 0) && reducedValue
  } else {
     return false
  }
}

这是非常粗鲁的实施,但我认为你会得到这个想法

© www.soinside.com 2019 - 2024. All rights reserved.