Reputation: 153
I have an Array of Dictionaries defined as
var users = [[String:String]]()
The Dictionary inside the array is a simple username + yes/no flag [[1stUser: Y], [2ndUser: N], [3rdUser: N]]
In my TableView cell configuration, I defined
let userRecord = users[indexPath.row] as NSDictionary
and need to assign cell.textlabel.text = username (the key of the dictionary)
check flag (Y/N) and if Yes > cell.accessoryType = UITableViewCellAccessoryType.Checkmark
In the example above, I should get a checkmark next to 1stUser only.
The question is how to refer to the dictionary keys ('1stUser', '2nduser' etc.) without knowing them in advance and check values (Y/N)? All the Swift dictionary examples I have seen assume we know the actual key to retrieve its value (e.g users["1stUser"] does not help as I do not know in advance that 1stUser has a Y).
Upvotes: 4
Views: 4866
Reputation: 66302
You should always know your dictionary keys. If you don't, you're structuring your data wrong - unknown data should always be in the value of a dictionary, never the key.
Consider instead using a dictionary with two keys: "username" and "flag".
Sample code:
var users = [[String:String]]()
users.append(["username" : "Aaron", "flag" : "yes"])
users.append(["username" : "AspiringDeveloper", "flag" : "yes"])
let userRecord = users[1]
let username = userRecord["username"]!
let flag = userRecord["flag"]!
Alternatively, you could build a basic class and avoid the dictionaries entirely:
class User {
let username: String
let flag: Bool
init(username:String, flag:Bool) {
self.username = username
self.flag = flag
}
}
var users = [User]()
users.append(User(username: "Aaron", flag: true))
users.append(User(username: "AspiringDeveloper", flag: true))
let userRecord = users[1]
let username = userRecord.username
let flag = userRecord.flag
Upvotes: 1
Reputation:
Without knowing the key(s) in advance, there is no other way than enumerating all (key, value) pairs (like @valfer said) and test the flag value. A dictionary will not support queries such as "report all entries having a True value".
Your problem statement is not clear about whether there is always exactly one True flag or not. If yes, you can stop the scan as soon as you found it.
Upvotes: 0
Reputation: 51911
I agree with @AaronBrager answer, but...
If you are sure the dictionary has at least one value, and no more than one value, you can
let dict = ["user1":"yes"]
// retrieve the key and the value
let (key, val) = dict[dict.startIndex] // -> key == "user1", val == "yes"
// retrieve the key
let key = dict.keys.first! // -> key == "user1"
So, let's convert [[String:String]]
to [(name:String,flag:Bool)]
let users:[[String:String]] = [["1stUser": "Y"], ["2ndUser": "N"], ["3rdUser": "N"]]
let usersModified = users.map { dict -> (name:String, flag:Bool) in
let (key, val) = dict[dict.startIndex]
return (
name: key,
flag: val == "Y" ? true : false
)
}
By doing that you can simply:
let user = usersModified[indexPath.row]
cell.textLabel.text = user.name
cell.accessoryType = user.flag ? .Checkmark : .None
Upvotes: 1
Reputation: 3545
You can iterate on a dictionary using:
for (key, value) in myDictionary {
// here use key and value
}
Upvotes: 0