bssrdf
bssrdf

Reputation: 85

Swift Set value in a Dictionary does not grow after first element added

I have the following Swift code to mimic twitter follow/unfollow. I expect it to print out 2,1,5 or 1,2,5 but instead, I only got 2 printed out. What's wrong with my code? Thanks.

public struct Twitter {
    var followees = [Int: Set<Int>]()

    public mutating func follow(_ followerId: Int, _ followeeId: Int){
        if var user = followees[followeeId] {
            user.insert(followerId)
        }
        else{
            var user = Set<Int>()
            user.insert(followerId)
            followees[followeeId] = user
        }

    }
    public mutating func unfollow(_ followerId: Int, _ followeeId: Int){
        guard let id = followees[followeeId]?.remove(followerId) else{
            print("user \(followeeId) does not has a follower with id \(followerId)")
            return
        }
    }
    public func printFollowers(_ userId: Int) {
        if let followers = followees[userId] {
            for id in followers{
                print("follower id is \(id)")
            }
        }else{
            print("no such user with id \(userId)")
        }
    }
}


var twitter = Twitter()
twitter.follow(1, 2)
twitter.follow(2, 3)
twitter.follow(1, 3)
twitter.follow(5, 3)
twitter.printFollowers(3)

Upvotes: 0

Views: 94

Answers (1)

Aaron Cyrman
Aaron Cyrman

Reputation: 556

The problem is that in Swift dictionaries and arrays are value types, not reference. So in your function follow when you do if var user = followees[followeeId] that variable is not a reference to the set in followees property, any insert you do over user is lost when the then scope ends.

You can rewrite your follow function like this:

public mutating func follow(_ followerId: Int, _ followeeId: Int){
  if !followees.keys.contains(followeeId) {
     followees[followeeId] = Set<Int>()
  }
  followees[followeeId]?.insert(followerId)
}

Upvotes: 1

Related Questions