2016-12-07 2 views
-2

장면Comment과 같은 배열이 var comments:[Comment]? 인 배열이 있습니다. 이 클래스는 commentBy이고 User이라는 NSObject 클래스이며 고유 사용자를 식별 할 수있는 속성이 있습니다 (var key:String). 코드로 설명 위

, 나는 세 가지 의견이있다, 그래서
내가, userA 2 인 코멘트를 한 것으로 나타났습니다하고 userB 1 개 코멘트를했다 있다고 가정 코멘트의 독특한 배열을 원하는 원하는 것은
Swift3.0에서 유일한 배열을 얻는 방법

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


총,하지만 내 유일한 배열에 , 나는 두 사용자가 의견을 만든 것을 보여주고 싶습니다.

어떻게해야합니까?

+3

제목과 관련하여 "NSSet"과 관련이 있습니까? –

+2

왜 댓글과 사용자가 'NSObject'에서 파생 되었습니까? 나는 그것들을'Structs'로 가지는 것이 훨씬 더 낫다고 생각합니다. – 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입니까? Set 또는 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 

set3

항상 [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 때문에

은 이미 당신이 그 키를 기반으로 비교하기를 오버라이드 (override) isEqual:를 사용 ==의 구현이있는 NSObject입니다. User 해시 값으로 hashValuekey을 사용합니다.

이제 User을 사전 세트의 키로 사용할 수 있습니다. Comment에 대해 동일한 작업을 수행하여 User에있는 동등 물을 비교할 경우 세트의 주석도 사용할 수 있습니다. 그러나 그것은 나쁜 생각입니다. 두 명의 의견은 동일한 사용자를 갖고 있기 때문에 동일하지 않습니다.

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 당신이 요청 수입니다 : 다음과 같이 사용자가 키가 사전을 사용하는 SomeClass을 변경해야합니다. commentCount 속성은 총 주석 수입니다.주의해야하지만 구현은 O (n) 시간에 실행됩니다. 속도가 핵심이라면 주석을 추가 할 때마다 증가하는 카운터를 유지해야합니다.

관련 문제