Named key/value pairs in a Swift dictionaries - ios

Is there a way to have named key/value pairs in a Swift dictionaries? I'd rather use a name instead of an index number to refer to either the key or the value.
Unfortunately, key/value pairs by name in Dictionary in Swift only discusses referring to the keys and values in a for-loop. I'd like to give the keys and values a name when I declare them in the typealias so they can always be referred to by their names.
Please see the comment in the below code snippet to show what I mean:
typealias CalendarRules = [EKCalendar : [String]]
let calendarRules = buildCalendarRules() // builds the array.
let firstCalendarRule = calendarRules.first
print(firstCalendarRule.0) // I'd like to write: print(firstCalendarRule.cal)
print(firstCalendarRule.1) // I'd like to write: print(firstCalendarRule.theString)

This has nothing to do with dictionaries, except very indirectly; and your CalendarRules type alias is irrelevant. Your firstCalendarRule is not a dictionary; it is a tuple. You are free to name the members of a tuple:
typealias Rule = (cal:String, string:String)
let d = ["I am a calendar":"I am a string"]
let firstRule : Rule = d.first!
print(firstRule.cal) // I am a calendar

Related

Swift 3: how to sort Dictionary's key and value of struct

This is my Struct,by Swift 3. I know the Dictionary is not stored sequence like an Array and that is my problem. I want to get my Dictionary sequence as I set in ViewArray. I can get the ctC Dictionary, but how can i sort the keys or values as i set in ViewArrayplease and appreciate the help.
struct CTArray {
var ctname: String
var ctkey: String
var ctC: [String:String]
}
var ViewArray:[CTArray] = []
ViewArray += [CTArray(ctname: "kerish", ctkey: "KH", ctC: ["mon":"Apple", "kis":"aone", "Bat":"Best", "orlno":"bOne"])]
ViewArray += [CTArray(ctname: "tainers", ctkey: "TNN", ctC: ["letGor":"one", "washi":"testing", "monk":"lasth"])]
ViewArray += [CTArray(ctname: "techiu", ctkey: "TCU", ctC: ["22":"tt", "wke":"303", "lenth":"highest"])]
i want to show them in my TableView Cell sorted like these:
the ViewArray[0].ctC.key sorted like [mon, kis, Bat, orlno]
the ViewArray[1].ctC.key sorted like [letGor, washi, monk]
the ViewArray[2].ctC.value sorted like [tt, 303, highest]
It is not clear to me what you are asking, but I'll offer this in case it helps.
I know the Dictionary is not stored sequence like an Array and that is my problem.
If you want to access a dictionary by a certain order of its keys then you can create an array of just the keys in the order you required and use that to access the dictionary. An example is probably easier to follow:
Starting with one of your dictionaries:
let dict = ["mon":"Apple", "kis":"aone", "Bat":"Best", "orlno":"bOne"]
print(dict)
this output:
["Bat": "Best", "kis": "aone", "orlno": "bOne", "mon": "Apple"]
which is not what you want. Now introduce a key array and use that to access the dictionary:
let keyOrder = ["mon", "kis", "Bat", "orlno"]
for key in keyOrder
{
print("\(key): \(dict[key]!)")
}
this outputs:
mon: Apple
kis: aone
Bat: Best
orlno: bOne
which is the order you wish.
The same idea can be used anywhere you want to use/show/etc. the keys in a particular order, by using the keyOrder array as part of dictionary access you are making it appear as though the dictionary entries are "stored in sequence" as you put it.
HTH
var object1 = viewArray[0].ctC.flatMap({$0.key})
var object2 = viewArray[1].ctC.flatMap({$0.key})
var object3 = viewArray[2].ctC.flatMap({$0.value})
print(object1)
print(object2)
print(object3)
Outputs:
["Bat", "kis", "orlno", "mon"]
["letGor", "monk", "washi"]
["highest", "tt", "303"]

Can we create a Dictionary with Generic?

In Stanford's class(see the picture 1), the professor initialized a Dictionary like this:
var a = Dictionary<String: Int>()
But it cannot work in my computer(see the picture 2), is there something wrong?
Dictionary is a generic struct, whose generic type parameters can be defined in the same way as any other generic struct, using a comma separated list in angle brackets:
let a = Dictionary<String, Int>()
There's also a special syntactic sugar that's specific to dictionaries, that let you express the same as above as:
let a = [String: Int]()
Mixing the two together as in Dictionary<String: Int> is invalid.

Create an array in swift

I'm searching really much, but maybe I can't understand the results.
I found only that a array in SWIFT have as index int-values
var myArray = [String]()
myArray.append("bla")
myArray.append("blub")
println(myArray[0]) // -> print the result bla
But I will add a String with an String as index-key
var myArray = [String:String]()
myArray.append("Comment1":"bla")
myArray.append("Comment2":"blub")
println(myArray["Comment1"]) // -> should print the result bla
How should i declare the array and how I can append a value then to this array?
Your second example is dictionary
myArray["key"] = "value"
If you want array of dictionaries you would have to declare it like this
var myArray: [[String: String]]
Your first example is an array. Your second example is a dictionary.
For a dictionary you use key value pairing...
myArray["Comment1"] = "Blah"
You use the same to fetch values...
let value = myArray["Comment1"]
println(value)
You got the concept of array in the first example but for the second one you need a dictionary as they operate on key value pair
// the first String denotes the key while the other denotes the value
var myDictionary :[String:String] = ["username":"NSDumb"]
let value = myDictionary["username"]!;
println(value)
Quick reference for dictionaries collection type can be found here

How to create and access a NSDictionary in Swift

I am busy converting to Swift and am trying to figure out how to do the following in Swift
NSArray arrayOfStrings1 = {#"Substring1", #"Substring2", nil};
Dictionary dict = {#"MainString1", arrayOfStrings1};
So in Swift I have the following:
var dictionary = [String: Array<String>]() // is this correct ??
var array: [String] = ["Substring1", "Substring2"]
dictionary["MainString1"] = ["Substring1.1", "Substring1.2"]
dictionary["MainString2"] = ["Substring2.1", "Substring2.2"]
Now in order to access the array I use
let array = dictionary["MainString1"]
let item0 = array[0]
but this fails with a compiler error which seems to indicate that array is in fact a String not an array of strings.
What am I missing here?
The issue is actually that a subscript lookup for a Dictionary in Swift returns an optional value:
This is a pretty great feature - you can't be guaranteed that the key you're looking for necessarily corresponds to a value. So Swift makes sure you know that you might not get a value from your lookup.
This differs a little bit from subscript behavior for an Array, which will always return a value. This is a semantically-driven decision - it's common in languages for dictionary lookups to return null if there is no key - but if you try to access an array index that does not exist (because it's out of bounds), an exception will be thrown. This is how Swift guarantees you'll get a value back from an array subscript: Either you'll get one, or you'll have to catch an exception. Dictionaries are a little more lenient - they're "used to" not having the value you're asking for.
As a result, you can use optional binding to only use the item if it actually has a value, like so:
if let theArray = dictionary["MainString1"] {
let item0 = theArray[0]
} else {
NSLog("There was no value for key 'MainString1'")
}

Trouble Unpacking Dictionary of Dictionaries in Swift

I am having a devil of a time trying to work with Dictionaries in Swift. I have created the following Dictionary of Dictionaries but I am unable to unpack it.
var holeDictionary = Dictionary<String,Dictionary<String,Dictionary<String,Int>>>()
I can get the first Dictionary out with:
var aDictionary = holeDictionary["1"]
But trying to access the next Dictionary within it gives me an error as follows:
var bDictionary = aDictionary["key"] // [String : Dictionary<String, Int>]?' does not have a member named 'subscript'
I know what the contents of the Dictionaries are and can verify them with a println(aDictionary). So how can I get to the Dictionaries buried deeper down?
The key subscript on Dictionary returns an optional, because the key-value pair may or may not exist in the dictionary.
You need to use an if-let binding or force unwrap the optional before you can access it to subscript it further:
if let aDictionary = holeDictionary["1"] {
let bDictionary = aDictionary["key"]
}
Edit, to add forced unwrap example:
If you're sure that the key "1" exists, and you're okay with assert()ing at runtime if the key doesn't exist, you can force-unwrap the optional like this:
let bDictionary = holeDictionary["1"]!["key"]
And if you're sure that the key "key" will exist, you'd do this instead:
let bDictionary = holeDictionary["1"]!["key"]!
Accordingly to the swift documentation:
Because it is possible to request a key for which no value exists,
a dictionary’s subscript returns an optional value of the dictionary’s
value type
When you retrieve an item from a dictionary you have an optional value returned. The correct way to handle your case is:
var holeDictionary = Dictionary<String,Dictionary<String,Dictionary<String,Int>>>()
if let aDictionary = holeDictionary["1"] {
var bDictionary = aDictionary["key"]
}

Resources