场景,我有一个名为NSObject
的{{1}}类数组,如Comment
。此类具有属性var comments:[Comment]?
,该属性也是名为commentBy
的{{1}}类,并且它具有标识唯一用户NSObject
的属性。
< em>以上描述为代码,
User
我想要什么
我想要一个独特的评论数组,假设var key:String
发表了2条评论而class Comment:NSObject {
var commentBy:User?
}
class User:NSObject {
var key:String?
}
//In some other class
class someClass {
var comments:[Comment]?
}
发表了1条评论,所以总共有三条评论,但在我独特的数组中,我想展示一下两位用户发表评论。
我该怎么办?
答案 0 :(得分:2)
var comments: [Comment]?
let userKeys = comments?.flatMap { $0.commentBy?.key } ?? []
let set = Set(userKeys)
如果您想要的只是已注释的唯一身份用户的总数,那么我认为将注释映射到用户的密钥然后创建一组密钥更快。
答案 1 :(得分:0)
看看我做了什么,实际上你的问题是How to init a NSSet in swift
?
class Comment:NSObject {
var commentBy:User?
}
class User:NSObject {
var key:String?
}
//In some other class
class someClass {
var comments:[Comment]?
}
let user1 = User()
user1.key = "1"
let user2 = User()
user1.key = "2"
let c1 = Comment()
c1.commentBy = user1
let c2 = Comment()
c2.commentBy = user1
let c3 = Comment()
c3.commentBy = user2
let set: NSSet = [user1, user2]
let set2: NSSet = [user2]
set2.isSubset(of: set as! Set<AnyHashable>) //true
let set3: NSSet = [c1, c1]
set3.count //1
let set4: NSSet = [c1, c2, c3] // your unique array
let set5 = NSSet(array: [c1, c2, c1, c3])
set5.count //3
set3
始终为[c1]
,因为Set
或NSSet
中的元素将是唯一的。
答案 2 :(得分:0)
首先使User
可以通过基于其唯一键使其相等的方式进行哈希。
class User: NSObject
{
let key:String
init(key: String) { self.key = key }
override func isEqual(_ object: Any?) -> Bool
{
guard let other = object as? User else { return false }
return self.key == other.key
}
override var hashValue: Int { return key.hashValue }
}
let eq = User(key: "foo") == User(key: "foo") // true
let h1 = User(key: "foo").hashValue // some big number
let h2 = User(key: "foo").hashValue // same big number as above
我已将key
变为不可变因为,因为它可以唯一地标识用户,所以不应该更改。
由于User
是NSObject
,因此它已经有==
的实现,它使用isEqual:
,因此您可以根据密钥覆盖它以进行比较。您还使用hashValue
key
作为User
哈希值。
现在,您可以在集合中使用User
,也可以在词典中使用键。如果您对Comment
执行相同操作,以便它们在User
上进行比较,则您也可以在集合中使用注释。但是,这是个坏主意。两条评论不同,只是因为它们拥有相同的用户。您应该更改SomeClass
以使用用户键入的字典,如下所示:
class Comment: NSObject
{
let user: User
let text: String
init(user: User, text: String)
{
self.user = user
self.text = text
}
}
class SomeClass
{
var userComments: [User : [Comment]] = [:]
func addComment(newComment: Comment)
{
if let existingComments = userComments[newComment.user]
{
userComments[newComment.user] = existingComments + [newComment]
}
else
{
userComments[newComment.user] = [newComment]
}
}
var userCount: Int { return userComments.count }
var commentCount: Int { return userComments.values.reduce(0, { $0 + $1.count}) }
}
属性userCount是您要求的号码。属性commentCount是注释的总数 - 尽管要注意:实现在O(n)时间内运行。如果速度至关重要,则应该维护一个计数器,每次添加注释时该计数器都会递增。