How do i init dictionary with range of keys in swift? - swift

Here is a swift dictionary declaration:
var cardField = [Int:Card]()
How can i init a keys for this dictionary, using range syntax?
Something like that:
var cardField: [Int:Card] = [0...5:nil]
This is doesn't work...
Thank you.

Unfortunately, Range isn't a Sequence, so it can't be directly passed to reduce(into:) stride is though, so you can use something like:
let cardField = Dictionary(uniqueKeysWithValues: stride(from: 0, to: 5, by: 1).map { ($0, "\($0)" )})
The biggest problem is you haven't specified what the value of the keys should be, so without that information we're really just poking in the dark.

You could create an array then add it to a dictionary:
var values = Array(1...5)
let keyToValue = Dictionary(uniqueKeysWithValues: zip(values, 1...5))
print(keyToValue[3]!)
// Prints 3
print(keyToValue)
// Prints [5: 5, 2: 2, 3: 3, 1: 1, 4: 4]

Related

Is it safe to remove values from a dictionary while iterating in swift?

So my code hasn't crashed, but this feels like it shouldn't be safe, but I can't find a clear answer in the swift docs. I'm iterating over a dictionary with a for-in loop and removing those elements if not found in a reference array. I'm wondering if this is safe, and if so, why?
func cleanupETADictionary(trips: [Int64]){
for (tripId, _) in etaDictionary{
if !trips.contains(tripId){
etaDictionary.removeValue(forKey: tripId)
}
}
}
The iteration does not work like you're thinking it does. Your iterated etaDictionary is a copy of the original. Dictionaries are value types in Swift.
Clear example:
var dictionary = [1: 1, 2: 2, 3: 3, 4: 4, 5: 5]
for kvp in dictionary {
dictionary = [:]
print(kvp)
print(dictionary.count)
}
outputs:
(key: 5, value: 5)
0
(key: 3, value: 3)
0
(key: 4, value: 4)
0
(key: 1, value: 1)
0
(key: 2, value: 2)
0
There's a name for your for loop, though; it is called filter. Use it instead.
func cleanupETADictionary(trips: [Int64]){
etaDictionary = etaDictionary.filter { trips.contains($0.key) }
}

How can I prevent or stop dictionary values from being nill?

I have a dictionary and a array of strings
The keys and values are generated with for loop
for some reason , all values in dictionary are nill.
Create a empty dictionary
Create a string array
Create for loop to generate keys and values
keys become i.e. KEY_15.
values would be a random number
Create for loop to check if the dictionary contains any of the elements in the array
For each existing key that matches arr element, check if that key value is even or not i.e if(arr[0] == dictionary key)
if even, change dictionary value to 0 i.e. if arr contains element with string "Key_12" and dictionary contains a key with the name "Key_12", then value becomes 0.]
Making 2 for loops to match but problem still occurs
//Code Starts Here
var arr : [String] = ["KEY_10", "Bear", "KEY_23", "KEY_12"] // string array
var dic: [String : Int] = [:] //default dic
let ran: Int? = Int.random(in: 0...10) //generate random value
for i in 10...24{ //create elements to dic
let iAsString = String(i)
let stringWithZero = "KEY_" + iAsString
dic[stringWithZero] = ran!
}
for x in arr{
let dickeys: [String] = [String](dic.keys) //store keys
let element = x
for y in 0...dickeys.count-1{
let dicKey = dickeys[y]
if dicKey == element{ //never runs
if dic[x]! % 2 == 0{
dic.updateValue(0, forKey: x) //update value to 0
}
}
}
}
Your code works, but it isn't efficient.
Here is a cleaned up version:
var arr = ["KEY_10", "Bear", "KEY_23", "KEY_12"] // string array
var dic: [String : Int] = [:] //default dic
for i in 10...24 { //create elements to dic
dic["KEY_\(i)"] = Int.random(in: 0...10)
}
print(dic)
for x in arr {
if let value = dic[x] {
if value % 2 == 0 {
dic[x] = 0
}
}
}
print(dic)
Output:
["KEY_19": 2, "KEY_22": 5, "KEY_11": 7, "KEY_21": 3, "KEY_15": 8, "KEY_14": 6, "KEY_12": 6, "KEY_17": 9, "KEY_23": 3, "KEY_16": 1, "KEY_18": 1, "KEY_24": 4, "KEY_10": 0, "KEY_13": 8, "KEY_20": 1]
["KEY_19": 2, "KEY_22": 5, "KEY_11": 7, "KEY_21": 3, "KEY_15": 8, "KEY_14": 6, "KEY_12": 0, "KEY_17": 9, "KEY_23": 3, "KEY_16": 1, "KEY_18": 1, "KEY_24": 4, "KEY_10": 0, "KEY_13": 8, "KEY_20": 1]
Notes:
You should move the generation of the random Int into the first loop so that each key potentially gets a different random value.
Let Swift infer types wherever possible (eg. use var array = ["KEY_10"] instead of var array: [String] = ["KEY_10"]).
Use string interpolation to create "KEY_10" through "KEY_24".
To check if a key exists in a dictionary, just look it up. There is no need to loop over all of the keys of the dictionary. The value returned is an optional that is nil if the key doesn't exist. Use optional binding to unwrap that value.
if let value = dic[x] {
// we only get here if key x exists
// value is then the unwrapped value corresponding to key x
}
dic.updateValue(0, forKey: x) is better written as dic[x] = 0.

Cannot use optional chaining on non-optional value of type '[Int]'

I am trying to make my code print "Hello World" in Swift 4 by selecting just one of the three numbers in the array and I get the error listed in the title.
func newFunc() {
let employees = [1, 2, 3]?
if employees == [1] {
let printthis = "Hello World!"
print(printthis)
} else {
print("Nothing here")
}
}
newFunc()
You cannot apply "?" Optional to the object/instance. you can define an object as an Optional by putting the "?" on the type:
let employees: [Int]? = [1, 2, 3]
you employees array will be now an array of Optional Int. It seems that you don't need an optional so you can skip "?" from the defining
And for checking if an array contains a value you can check it by:
if employees.contains(1) {
let printthis = "Hello World!"
print(printthis)
} else {
print("Nothing here")
}
the problem is here
let employees = [1, 2, 3]?
should be like this , you can't append ? for that declaration
let employees = [1, 2, 3]
The code
let employees = [1, 2, 3]?
Is not valid Swift.
If you want to create an optional Array of Ints, use
let employees: [Int]? = [1, 2, 3]
However, it's unlikely that you want an optional let constant. It's probably better to just get rid of the question mark:
let employees = [1, 2, 3]
If you really want employees to be an optional array, and you really want to put the optional specifier on the right-hand side of the declaration, you could do it like this:
let employees = Optional([1, 2, 3])
But again I'm not sure why you'd want an optional let constant as an instance var.

How do you find a maximum value in a Swift dictionary?

So, say I have a dictionary that looks like this:
var data : [Float:Float] = [0:0,1:1,2:1.414,3:2.732,4:2,5:5.236,6:3.469,7:2.693,8:5.828,9:3.201]
How would I programmatically find the highest value in the dictionary? Is there a "data.max" command or something?
let maximum = data.reduce(0.0) { max($0, $1.1) }
Just a quick way using reduce.
or:
data.values.max()
Output:
print(maximum) // 5.828
A Swift Dictionary provides the max(by:) method. The Example from Apple is as follows:
let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
let greatestHue = hues.max { a, b in a.value < b.value }
print(greatestHue)
// Prints "Optional(("Heliotrope", 296))"
Exist a function in the API, named maxElement you can use it very easy , that returns the maximum element in self or nil if the sequence is empty and that requires a strict weak ordering as closure in your case as you use a Dictionary. You can use like in the following example:
var data : [Float:Float] = [0:0,1:1,2:1.414,3:2.732,4:2,5:5.236,6:3.469,7:2.693,8:5.828,9:3.201]
let element = data.maxElement { $0.1 < $1.1} // (.0 8, .1 5.828)
And get the maximum value by the values, but you can change as you like to use it over the keys, it's up to you.
I hope this help you.
Honestly the solutions mentioned above - work, but they seem to be somewhat unclear to me as a newbie, so here is my solution to finding the max value in a Dictionary using SWIFT 5.3 in Xcode 12.0.1:
var someDictionary = ["One": 41, "Two": 17, "Three": 23]
func maxValue() {
let maxValueOfSomeDictionary = someDictionary.max { a, b in a.value < b.value }
print(maxValueOfSomeDictionary!.value)
}
maxValue()
After the dot notation (meaning the ".") put max and the code inside {} (curly braces) to compare the components of your Dictionary.
There are two methods to find max value in the dictionary.
First approach:
data.values.max
Second approach:
data.max { $0.value < $1.value}?.value
If you want to find max key:
data.max { $0.key < $1.key}?.key

Swift: build a dictionary with keys from array1, and values from array2

Here are 2 arrays: countriesVotedKeys and dictionnaryCountriesVotes.
I need to build a dictionary, whose keys are all the items from countriesVotedKeys, and its values are all the items from dictionnaryCountriesVotes. Both arrays contains same number of elements.
I've tried many things, but none lead to desired result.
for value in self.countriesVotedValues! {
for key in self.countriesVotedKeys! {
self.dictionnaryCountriesVotes![key] = value
}
}
I can clearly see why this code produce bad result: second array is iterated in its entirity at each iteration of first array. I also tried a classical for var i= 0, var j= 0;...... but it seems this kind of syntax is not allowed in swift.
In short, i'm stuck. Again.
Swift 4
let keys = ["key1", "key2", "key3"]
let values = [100, 200, 300]
let dict = Dictionary(uniqueKeysWithValues: zip(keys, values))
print(dict) // "[key1: 100, key3: 300, key2: 200]"
Swift 3
var dict: [String: Int] = [:]
for i in 0..<keys.count {
dict[keys[i]] = values[i]
}
Use NSDictionary's convenience initializer:
let keys = ["a", "b", "c"]
let values = [1,2,3]
var dict = NSDictionary(objects: values, forKeys: keys) as [String: Int]