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

时间:2016-12-07 10:12:24

标签: arrays swift3 ios10

场景,我有一个名为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条评论,所以总共有三条评论,但在我独特的数组中,我想展示一下两位用户发表评论

我该怎么办?

3 个答案:

答案 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],因为SetNSSet中的元素将是唯一的。

答案 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变为不可变因为,因为它可以唯一地标识用户,所以不应该更改。

由于UserNSObject,因此它已经有==的实现,它使用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)时间内运行。如果速度至关重要,则应该维护一个计数器,每次添加注释时该计数器都会递增。