Reputation: 12820
I have a Dictionary
in Swift and I would like to get a key at a specific index.
var myDict : Dictionary<String,MyClass> = Dictionary<String,MyClass>()
I know that I can iterate over the keys and log them
for key in myDict.keys{
NSLog("key = \(key)")
}
However, strangely enough, something like this is not possible. Why not?
var key : String = myDict.keys[0]
Upvotes: 145
Views: 194150
Reputation: 130193
That's because keys
returns LazyMapCollection<[Key : Value], Key>
, which can't be subscripted with an Int
. One way to handle this is to advance the dictionary's startIndex
by the integer that you wanted to subscript by, for example:
let intIndex = 1 // where intIndex < myDictionary.count
let index = myDictionary.index(myDictionary.startIndex, offsetBy: intIndex)
myDictionary.keys[index]
Another possible solution would be to initialize an array with keys
as input, then you can use integer subscripts on the result:
let firstKey = Array(myDictionary.keys)[0] // or .first
Remember, dictionaries are inherently unordered, so don't expect the key at a given index to always be the same.
Upvotes: 248
Reputation: 5596
Here is a small extension for accessing keys and values in dictionary by index:
extension Dictionary {
subscript(i: Int) -> (key: Key, value: Value) {
return self[index(startIndex, offsetBy: i)]
}
}
Upvotes: 29
Reputation: 1365
I was looking for something like a LinkedHashMap in Java. Neither Swift nor Objective-C have one if I'm not mistaken.
My initial thought was to wrap my dictionary in an Array. [[String: UIImage]]
but then I realized that grabbing the key from the dictionary was wacky with Array(dict)[index].key
so I went with Tuples. Now my array looks like [(String, UIImage)]
so I can retrieve it by tuple.0
. No more converting it to an Array. Just my 2 cents.
Upvotes: 0
Reputation: 2061
Slightly off-topic: But here is if you have an Array of Dictionaries i.e: [ [String : String] ]
var array_has_dictionary = [ // Start of array
// Dictionary 1
[
"name" : "xxxx",
"age" : "xxxx",
"last_name":"xxx"
],
// Dictionary 2
[
"name" : "yyy",
"age" : "yyy",
"last_name":"yyy"
],
] // end of array
cell.textLabel?.text = Array(array_has_dictionary[1])[1].key
// Output: age -> yyy
Upvotes: 3
Reputation: 11762
In Swift 3 try to use this code to get Key-Value Pair (tuple) at given index:
extension Dictionary {
subscript(i:Int) -> (key:Key,value:Value) {
get {
return self[index(startIndex, offsetBy: i)];
}
}
}
Upvotes: 7
Reputation: 6795
Swift 3 : Array()
can be useful to do this .
Get Key :
let index = 5 // Int Value
Array(myDict)[index].key
Get Value :
Array(myDict)[index].value
Upvotes: 70
Reputation: 3225
SWIFT 3. Example for the first element
let wordByLanguage = ["English": 5, "Spanish": 4, "Polish": 3, "Arabic": 2]
if let firstLang = wordByLanguage.first?.key {
print(firstLang) // English
}
Upvotes: 8
Reputation: 117
Here is an example, using Swift 1.2
var person = ["name":"Sean", "gender":"male"]
person.keys.array[1] // "gender", get a dictionary key at specific index
person.values.array[1] // "male", get a dictionary value at specific index
Upvotes: 2
Reputation: 2384
You can iterate over a dictionary and grab an index with for-in and enumerate (like others have said, there is no guarantee it will come out ordered like below)
let dict = ["c": 123, "d": 045, "a": 456]
for (index, entry) in enumerate(dict) {
println(index) // 0 1 2
println(entry) // (d, 45) (c, 123) (a, 456)
}
If you want to sort first..
var sortedKeysArray = sorted(dict) { $0.0 < $1.0 }
println(sortedKeysArray) // [(a, 456), (c, 123), (d, 45)]
var sortedValuesArray = sorted(dict) { $0.1 < $1.1 }
println(sortedValuesArray) // [(d, 45), (c, 123), (a, 456)]
then iterate.
for (index, entry) in enumerate(sortedKeysArray) {
println(index) // 0 1 2
println(entry.0) // a c d
println(entry.1) // 456 123 45
}
If you want to create an ordered dictionary, you should look into Generics.
Upvotes: 11
Reputation: 16855
If you need to use a dictionary’s keys or values with an API that takes an Array instance, initialize a new array with the keys or values property:
let airportCodes = [String](airports.keys) // airportCodes is ["TYO", "LHR"]
let airportNames = [String](airports.values) // airportNames is ["Tokyo", "London Heathrow"]
Upvotes: 10