Swift Referencing dictionary key and value without knowing key
I have a Set of Dictionaries defined as
var users = [[String:String]]()
The dictionary inside the array is a simple username + yes / no [[1stUser: Y], [2ndUser: N], [3rdUser: N]]
In my TableView cell configuration, I have defined
let userRecord = users[indexPath.row] as NSDictionary
and need to assign cell.textlabel.text = username (dictionary key)
check flag (Y / N), and if Yes> cell.accessoryType = UITableViewCellAccessoryType.Checkmark
In the above example, I have to check the box next to the 1st server.
The question is how to access the dictionary keys ('1stUser', '2nduser', etc.) without knowing them in advance and check the values (Y / N)? All the Swift dictionary examples I've seen assume we know the actual key to retrieve its value (eg users ["1stUser"] don't help as I don't know ahead of time that 1User has Y).
source to share
You should always know the dictionary keys. If you don't, you are structuring your data incorrectly - unknown data must always be in a dictionary value, not a key.
Instead, use 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 can create a base class and exclude 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
source to share
I agree with @AaronBrager's answer, but ...
If you are sure that the dictionary has at least one meaning and at most one meaning, 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 translate [[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
)
}
Having done this, you can simply:
let user = usersModified[indexPath.row]
cell.textLabel.text = user.name
cell.accessoryType = user.flag ? .Checkmark : .None
source to share
Without knowing the key in advance, there is no other way than to list all the (key, value) pairs (like @valfer said) and check the flag value. The dictionary will not support queries such as "report all inputs as true".
In your statement of the problem, it is not clear whether exactly one True flag exists or not. If so, you can stop scanning as soon as you find it.
source to share