检查Realm列表属性是否包含其他列表的所有元素

时间:2018-03-02 13:22:14

标签: ios swift realm

我正在使用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. 对两个列表进行排序,然后比较它们以确定它们是否包含相同的用户
  3. 但我想知道是否有更有效的方法来确定一个列表包含另一个列表的所有元素(即使它们的顺序不相同)?

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

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

    let ackSet = Set(message.acknowledgedBy)
    let recipientSet = Set(message.recipients)
    let fullyAcknowledged = ackSet.isSubset(of: recipientSet)
    

1 个答案:

答案 0 :(得分:0)

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

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

如果两个不同的用户可以拥有相同的ID,那么我会编写自己的方法,这将需要id和amp;名称。然后,您可以使用[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
  }
}

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