As far as I know there are two ways to create an empty dictionary in swift
var randomDict = [Int:Int]()
or
var randomDict = Dictionary<Int, Int>()
Is there any difference between these? Both versions seems to work just the same.
No, both are same.
From Apple's Book on Swift:
The type of a Swift dictionary is written in full as Dictionary<Key, Value>
You can also write the type of a dictionary in shorthand form as [Key: Value]. Although the two forms are functionally identical, the shorthand form is preferred.
So
var randomDict = [Int:Int]()
and
var randomDict = Dictionary<Int, Int>()
both calls the initializer which creates an empty dictionary and are basically the same in different form.
A third way you could do it is:
var randomDict:[Int:Int] = [:]
They're all equivalent as far as the code goes. I prefer one of the shorthand versions.
Related
I am working on an application and I am relatively new to Swift where I am trying to initialize answerKeys with the keys of answer variable with the following code but it is showing an error.
Cannot assign value of type 'Dictionary<IntPoint, String>.Keys' to type 'LazyMapCollection<Dictionary<IntPoint, String>, IntPoint>' (aka 'LazyMapSequence<Dictionary<IntPoint, String>, IntPoint>')
I have gone through the documentation but couldn't fix this.
var answer:[IntPoint:String] = [:]
var answerKeys:LazyMapCollection<Dictionary<IntPoint,String>,IntPoint>
init() {
answerKeys = answer.keys
}
It may be that Dictionary.keys returned a LazyMapCollection in earlier Swift versions. In Swift 5 it is Dictionary<Key, Value>.Keys as can be seen from the documentation, in your case
var answerKeys: Dictionary<IntPoint, String>.Keys
But note that you can always access answer.keys in your code instead of assigning this to a separate property.
As far as I know, there are 4 ways to declare a dictionary in Swift:
var dict1: Dictionary<String, Double> = [:]
var dict2 = Dictionary<String, Double>()
var dict3: [String:Double] = [:]
var dict4 = [String:Double]()
It seems these four options yields the same result.
What's the difference between these?
All you're doing is noticing that you can:
Use explicit variable typing, or let Swift infer the type of the variable based on the value assigned to it.
Use the formal specified generic struct notation Dictionary<String,Double>, or use the built-in "syntactic sugar" for describing a dictionary type [String:Double].
Two times two is four.
And then there are in fact some possibilities you've omitted; for example, you could say
var dict5 : [String:Double] = [String:Double]()
And of course in real life you are liable to do none of these things, but just assign an actual dictionary to your variable:
var dict6 = ["howdy":1.0]
Based upon this question: << Is the a ScriptEngine or eval()-like function in Swift? >> I'm assuming the following would not work in Swift:
private let BROWN_COLOUR: UIColor = UIColor.brownColor()
...
var colourName: String = "BROWN"
var colour = self[ colourName + "_COLOUR" ] as UIColor!
Correct or not?
Thank you for reading.
No, you cannot do that out of the box. You can, however, use keyed subscription to solve this. Or even easier: use a dictionary to store your values and query that.
But if the object derives from NSObject and the instance variables are marked with #objc, you can query these instance variables with valueForKey.
I'm trying to do this:
var myBeacons: [NSUUID: [Int]] = [NSUUID(UUIDString:"74278BDA-B644-4520-8F0C-720EAF059935"): [1,1]]
but I get the following error:
'[NSUUID: [Int]]' is not convertible to '[NSUUID: [Int]]'
If I do:
var myBeacons2: [String: [Int]] = ["74278BDA-B644-4520-8F0C-720EAF059935": [1,1]]
It works
Did I miss something or does it look like bug ? (I'm using Xcode 7 beta)
Since not every String is a valid UUID the initialiser can fail. Thus the initialiser returns an Optional<NSUUID>. This to encourage code safety.
Depending on your needs you might check that you supplied a valid String for an UUID as follow:
let givenString = "74278BDA-B644-4520-8F0C-720EAF059935"
var myBeacons: [NSUUID: [Int]] = [:]
if let uuid = NSUUID(UUIDString: givenString) {
// Here we are sure that the uuid is valid
myBeacons[uuid] = [1, 1]
}
As Martin points out, NSUUID(UUIDString:) returns an optional. You need to unwrap it:
var myBeacons: = [
NSUUID(UUIDString:"74278BDA-B644-4520-8F0C-720EAF059935")!: [1,1]]
(Note the exclamation point after the call to the NSUUID initializer.)
I tested that under Xcode 6.3.2 and it works. I Haven't tested it under Xcode 7 though.
Edit:
In fact it would be better to use optional binding as outlined in #MatteoPiombo's answer. You should accept his answer since it gives you the most robust solution. (I'm voting for his answer. It's the best answer so far)
convenience init?(UUIDString string: String) returns an optional, try unwrap it as follow:
var myBeacons: [NSUUID: [Int]] = [NSUUID(UUIDString:"74278BDA-B644-4520-8F0C-720EAF059935")!: [1,1]]
I looked through docs some forums and found I can create an array in various ways. I am confused which one should we be using?
var testArray = [Int]()
testArray.append(1)
var anotherTestArray: [Int] = []
anotherTestArray.append(1)
var yetAnotherTestArray: Array<Int> = []
yetAnotherTestArray.append(1)
var yetYetYetAnotherTestArray = Array<Int>()
yetYetYetAnotherTestArray.append(1)
This is not empty array but It keeps it's type for each element to be strictly to an Int
var yetYetAnotherTestArray = [1]
I think the cleanest way to create an array is var testArray: [Int] = []
In swift array objects must be the same type. If you want to store different objects of different types use [AnyObject]. However, you should always know what is coming out of it. Since the returning type value will be AnyObject, you have to cast down the value to the type you want.
I really don't recommend using AnyObject as the type of your arrays unless you really know what you are doing.
Here is an example anyway:
let a: [AnyObject] = [1, "a"]
let b = a[0] // An Int
let c = a[1] // A String