Arrays 如何在Swift3.0中获得唯一数组

Arrays 如何在Swift3.0中获得唯一数组,arrays,swift3,ios10,Arrays,Swift3,Ios10,Scene,我有一个名为Comment的NSObject类数组,类似于var comments:[Comment]?。此类具有属性commentBy,该属性也是名为User的NSObject类,并且它具有将唯一用户标识为var key:String的属性,该用户是上述描述中的代码, 我想要什么 我想要一个唯一的评论数组,假设userA发表了2条评论,userB发表了1条评论,因此总共有3条评论,但是在我的唯一数组中,我想显示两个用户发表了评论 我该怎么办 var comments: [Comme

Scene,我有一个名为
Comment
NSObject
类数组,类似于
var comments:[Comment]?
。此类具有属性
commentBy
,该属性也是名为
User
NSObject
类,并且它具有将唯一用户标识为
var key:String

的属性,该用户是上述描述中的代码,

我想要什么
我想要一个唯一的评论数组,假设
userA
发表了2条评论,
userB
发表了1条评论,因此总共有3条评论,但是在我的唯一数组中,我想显示两个用户发表了评论

我该怎么办

var comments: [Comment]?
let userKeys = comments?.flatMap { $0.commentBy?.key } ?? []
let set = Set(userKeys)

如果您想要的只是已注释的唯一用户的总数,那么我认为将注释映射到用户的密钥然后创建一组密钥更快。

请看我所做的,实际上您的问题是
如何在swift中初始化NSSet

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
类注释:NSObject{
var注释人:用户?
}
类用户:NSObject{
变量键:字符串?
}
//在别的班
上课{
var注释:[注释]?
}
让user1=User()
user1.key=“1”
让user2=User()
user1.key=“2”
设c1=注释()
c1.commentBy=user1
设c2=注释()
c2.commentBy=user1
设c3=注释()
c3.commentBy=user2
let set:NSSet=[user1,user2]
让set2:NSSet=[user2]
set2.isSubset(of:set as!set)//true
设set3:NSSet=[c1,c1]
set3.count//1
让set4:NSSet=[c1,c2,c3]//您的唯一数组
设set5=NSSet(数组:[c1,c2,c1,c3])
set5.count//3

set3
将始终是
[c1]
,因为
Set
NSSet
中的元素将是唯一的。

首先使
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
作为
用户
哈希值

现在,您可以在集合中使用
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)时间内运行。若速度至关重要,那个么您应该维护一个计数器,该计数器在每次添加注释时递增

这与标题中提到的“NSSet”有关吗?为什么注释和用户来自
NSObject
?我认为将它们作为
Structs
更好,为什么
commentBy
是可选的?实际上,没有作者的评论是不存在的。@vadian我想它们是可选的,可以绕过没有初始值设定项的错误:D而不是创建初始值设定项:)@Fogmeister是的,很可能是另一条阻力最小的路径可选;-)
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}) }
}