检查领域列表属性是不是包含另一个列表的所有元素
Posted
技术标签:
【中文标题】检查领域列表属性是不是包含另一个列表的所有元素【英文标题】:Check if Realm list property contains all elements of another list检查领域列表属性是否包含另一个列表的所有元素 【发布时间】:2018-03-02 13:22:13 【问题描述】:我正在使用 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
列表中。我还认为我可以通过以下两步过程完成此操作:
-
比较
recipients
和acknowledgedBy
中的元素计数,确保它们相同;如果他们是……
对两个列表进行排序,然后比较它们以确定它们是否包含相同的用户
但我想知道是否有更有效的方法来确定一个列表包含另一个列表的所有元素(即使它们的顺序不同)?
编辑 ----------
看起来我也可以使用 Sets 来做出这样的决定:
let ackSet = Set(message.acknowledgedBy)
let recipientSet = Set(message.recipients)
let fullyAcknowledged = ackSet.isSubset(of: recipientSet)
【问题讨论】:
【参考方案1】:我认为 Sets 不是一个好选择,假设您在其中一个列表中有重复项,那么这是错误的选项。我强烈建议看看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
这是相当粗鲁的实现,但我想你会明白的
【讨论】:
以上是关于检查领域列表属性是不是包含另一个列表的所有元素的主要内容,如果未能解决你的问题,请参考以下文章