2016-12-07 1 views
-2

シーンにユニークな配列を取得するために、私はvar comments:[Comment]?ようCommentという名前NSObjectクラスの配列をしました。このクラスはcommentByという属性を持ち、Userという名前のNSObjectクラスでもあり、ユニークなユーザーを識別するプロパティーはvar key:Stringです。
コードとして説明上記

がどのようにSwift3.0

class Comment:NSObject { 
    var commentBy:User? 
} 
class User:NSObject { 
    var key:String? 
} 
//In some other class 
class someClass { 
    var comments:[Comment]? 
} 

私は
たい私は、コメントのユニークな配列をしたい、userAが2件のコメントをしたと3件のコメントがあるので、userBは1件のコメントをしたと仮定私のユニークな配列での合計、私は2人のユーザーがコメントを作ったことを示したい。

どうすればよいですか?

+3

タイトルに記載されている「NSSet」に関連していますか? –

+2

コメントとユーザーはなぜ「NSObject」から派生したのですか? '構造体 'として持っているほうがはるかに良いと思います。 – Fogmeister

+2

' commentBy'はオプションですか?実際には、著者のないコメントはありません。 – vadian

答えて

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

あなたが望むすべてがコメントしているユニークユーザーの合計数であれば、私は、ユーザーのキーにコメントをマッピングすることは、その後高速であるキーのセットを作成すると思います。

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 

set3SetまたはNSSetの要素が一意になりますので、必ず、[c1]になります。

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は、それがすでにisEqual:を使用していますので、あなたがキーに基づいて比較することでこれをオーバーライドし==の実装を持っているNSObjectですので。また、Userのハッシュ値としてhashValuekeyを使用します。

Userをセットで、辞書のキーとして使用できるようになりました。 Userの等価物を比較するようにCommentについて同じことを行う場合は、セット内のコメントも使用できます。しかし、それは悪い考えです。 2人のコメントは同じユーザーであるため同じではありません。プロパティUSERCOUNTはあなたが尋ねた番号です

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}) } 
} 

:あなたは次のようにユーザーをキーと辞書を使用するようにSomeClassを変更する必要があります。 commentCountプロパティはコメントの総数です。ただし、実装はO(n)時間で実行されます。スピードが本質的である場合は、コメントを追加するたびに増分するカウンタを維持する必要があります。