I want my top level dictionary "Products" to store only a non empty dictionary of sub products. Is there a way to write the code below with higher order functions like reduce function instead using if !subProductDictionary.isEmpty ?
var productDictionary = [String: Any]()
productDictionary["key 1"] = "value 1"
var subProductDictionary = [String: Any]()
if !subProductDictionary.isEmpty {
productDictionary["subProductsKey"] = subProductDictionary
}
*** edit
I would like to use the fact that when Dictionaries do not store nil values, so to transform subProductDictionary to nil
I don't know about higher-order functions here but this might be useful:
extension Dictionary {
var nonEmpty: Self? {
isEmpty ? nil : self
}
}
var things: [String: Any] = [:]
let dict: [String: Any] = [:]
things["A"] = dict
things["B"] = dict.nonEmpty
Possible solution:
var productDictionary = [String: Any]()
productDictionary["key 1"] = "value 1"
var subProductDictionary = [String: Any]()
if !subProductDictionary.isEmpty {
productDictionary["subProductsKey"] = subProductDictionary
}
*** "Optional with flatMap" instead "if"
productDictionary["subProductsKey"] = Optional(subProductDictionary).flatMap { $0.count == 0 ? nil : $0 }
Please find below the code for proper and correct understanding:
var dictUpdateTasks = [String: String]()
var arrAddSteps = [String]()
self.dictUpdateTasks["dDay"] = self.btnAddDate.titleLabel?.text
self.dictUpdateTasks["rem"] = self.btnRemindMe.titleLabel?.text
self.dictUpdateTasks["steps"] = arrAddSteps
Now , this is the error, on line
"self.dictUpdateTasks["steps"] = arrAddSteps"
// Error: Cannot assign value of type '[String]' to type 'String?'
Please guide. Thanks.
Reason:
dictUpdateTasks is of type [String:String], i.e. it can accept values only of type String.
dictUpdateTasks["steps"] = arrAddSteps
But in the above code, you are trying to add [String] type value to dictUpdateTasks.
Solution:
Change the type of dictUpdateTasks from [String: String] to [String: Any],
var dictUpdateTasks = [String: Any]()
If you are looking for something like checking if the value exists or not by using isEmpty property of both the String and [String], on a higher level you could create a protocol separately for that. But for this scenario I would not recommend this.
protocol EmptyIdentifiable {
var isEmpty: Bool { get }
}
extension String: EmptyIdentifiable { }
extension Array: EmptyIdentifiable where Element == String { }
var dictionary = [String: EmptyIdentifiable]()
dictionary["string"] = "value"
dictionary["array"] = ["values1", "values2"]
print(dictionary["string"]?.isEmpty)
print(dictionary["array"]?.isEmpty)
Normal solution in this current situation would be to use casting from Any to String or [String].
if let array = dictionary["array"] as? [String] {
print(array, array.isEmpty)
}
if let string = dictionary["string"] as? String {
print(string, string.isEmpty)
}
Here is the correct way to create a dictionary.
Correct syntax
var dictUpdateTasks = [String: Any]()
You have created a dictionary with [String: String]() and you are assigned String Array arrAddSteps instead of String.
Please try this :
Need to make your dictionary type [String : Any]() instead of [String : String]()
In your case it will accept only String type in value
var dictUpdateTasks = [String: Any]()
var arrAddSteps = [String]()
self.dictUpdateTasks["dDay"] = self.btnAddDate.titleLabel?.text
self.dictUpdateTasks["rem"] = self.btnRemindMe.titleLabel?.text
self.dictUpdateTasks["steps"] = arrAddSteps
print(self.dictUpdateTasks)
You have to use key value pair to assign string to dictionary.
I tried to append an array of dictionaries which are coming from server to a globally declared array.but i am getting an error like "Cannot convert value of type '[Any]' to expected argument type '[String : Any]'"if anyone helps me would be great.Thanks in advance
var pro = [[String:Any]]()
var productsdetails = Array<Any>()
productsdetails = userdata.value(forKey: "products") as! Array
print("response\(productsdetails)")
self.pro = self.pro.append(productsdetails)
print(self.pro)
Use this code like below, i hope this works
var pro = [[String:Any]]()
if let productsdetails = userdata.value(forKey: "products") as? [[String:Any]] {
print("response\(productsdetails)")
self.pro.append(productsdetails)
print(self.pro)
}
to solve this iterate
var pro = [[String:Any]]()
if let productsdetails = userdata.value(forKey: "products") as? [[String: Any]] {
for details in productsdetails {
pro.append(details)
}
}
or you may use directly self.pro = productsdetails if you not to want iterate
**image shows [String : String] as I have used [String : String] instead of [String : Any]*
You can try this: (Swift-4.2)
var data: [String: Any] = [
"key1": "example value 1",
"key2": "example value 2",
"items": []
]
for index in 1...3 {
let item: [String: Any] = [
"key": "new value"
]
// get existing items, or create new array if doesn't exist
var existingItems = data["items"] as? [[String: Any]] ?? [[String: Any]]()
// append the item
existingItems.append(item)
// replace back into `data`
data["items"] = existingItems
}
Answer same as: Append to array in [String: Any] dictionary structure
Can you show us your response which has key products? As there is mismatch with the variable pro and productdetails. As i see pro holds values as "Array of Dictionary with key as String type and Value as Any type" which again has Array above it and productdetails is expecting Array of Any type not the Array of Dictionary Type. Assuming your products has Array of String Type or can be even a class object type you can do it as below.
var pro = Array<Any>() //Or You can make Array<String>() or Array<CustomClass>()
var userdata:[String:[String]] = ["products":["One","Two","Three"]]
var productsdetails = Array<Any>()
productsdetails = userdata["products"] ?? []
print("response\(productsdetails)")
pro.append(productsdetails)
I need to create a Dictionary with dynamic keys.
At the end I need a Dictionary
I tried to use:
var animDictionary:[String:AnyObject]
for position in 1...10
{
let strImageName : String = "anim-\(position)"
let image = UIImage(named:strImageName)
animDictionary.setValue(image, forKey: strImageName) //NOT WORK
//BECAUSE IT'S NOT A NSMUTABLEDICTIONARY
}
So I tried:
var animMutableDictionary=NSMutableDictionary<String,AnyObject>()
for position in 1...10
{
let strImageName : String = "anim-\(position)"
let image = UIImage(named:strImageName)
animMutableDictionary.setValue(image, forKey: strImageName)
}
But I don't find the how to convert my NSMutableDictionary to a Dictionary. I'm not sure it's possible.
In the Apple doc, I found :
I don't know if it's possible to use it in my case.
Xcode 11 • Swift 5.1
You need to initialize your dictionary before adding values to it:
var animDictionary: [String: Any] = [:]
(1...10).forEach { animDictionary["anim-\($0)"] = UIImage(named: "anim-\($0)")! }
Another option is to use reduce(into:) which would result in [String: UIImage]:
let animDictionary = (1...10).reduce(into: [:]) {
$0["anim-\($1)"] = UIImage(named: "anim-\($1)")!
}
I am beginning to learn swift by following the iBook-The Swift Programming Language on Swift provided by Apple. The book says to create an empty dictionary one should use [:] same as while declaring array as []:
I declared an empty array as follows :
let emptyArr = [] // or String[]()
But on declaring empty dictionary, I get syntax error:
let emptyDict = [:]
How do I declare an empty dictionary?
var emptyDictionary = [String: String]()
var populatedDictionary = ["key1": "value1", "key2": "value2"]
Note: if you're planning to change the contents of the dictionary over time then declare it as a variable (var). You can declare an empty dictionary as a constant (let) but it would be pointless if you have the intention of changing it because constant values can't be changed after initialization.
You can't use [:] unless type information is available.
You need to provide it explicitly in this case:
var dict = Dictionary<String, String>()
var means it's mutable, so you can add entries to it.
Conversely, if you make it a let then you cannot further modify it (let means constant).
You can use the [:] shorthand notation if the type information can be inferred, for instance
var dict = ["key": "value"]
// stuff
dict = [:] // ok, I'm done with it
In the last example the dictionary is known to have a type Dictionary<String, String> by the first line. Note that you didn't have to specify it explicitly, but it has been inferred.
The Swift documentation recommends the following way to initialize an empty Dictionary:
var emptyDict = [String: String]()
I was a little confused when I first came across this question because different answers showed different ways to initialize an empty Dictionary. It turns out that there are actually a lot of ways you can do it, though some are a little redundant or overly verbose given Swift's ability to infer the type.
var emptyDict = [String: String]()
var emptyDict = Dictionary<String, String>()
var emptyDict: [String: String] = [:]
var emptyDict: [String: String] = [String: String]()
var emptyDict: [String: String] = Dictionary<String, String>()
var emptyDict: Dictionary = [String: String]()
var emptyDict: Dictionary = Dictionary<String, String>()
var emptyDict: Dictionary<String, String> = [:]
var emptyDict: Dictionary<String, String> = [String: String]()
var emptyDict: Dictionary<String, String> = Dictionary<String, String>()
After you have an empty Dictionary you can add a key-value pair like this:
emptyDict["some key"] = "some value"
If you want to empty your dictionary again, you can do the following:
emptyDict = [:]
The types are still <String, String> because that is how it was initialized.
Use this will work.
var emptyDict = [String: String]()
You can simply declare it like this:
var emptyDict:NSMutableDictionary = [:]
You have to give the dictionary a type
// empty dict with Ints as keys and Strings as values
var namesOfIntegers = Dictionary<Int, String>()
If the compiler can infer the type, you can use the shorter syntax
namesOfIntegers[16] = "sixteen"
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers = [:]
// namesOfIntegers is once again an empty dictionary of type Int, String
Declaring & Initializing Dictionaries in Swift
Dictionary of String
var stringDict: [String: String] = [String: String]()
OR
var stringDict: Dictionary<String, String> = Dictionary<String, String>()
Dictionary of Int
var stringDict: [String: Int] = [String: Int]()
OR
var stringDict: Dictionary<String, Int> = Dictionary<String, Int>()
Dictionary of AnyObject
var stringDict: [String: AnyObject] = [String: AnyObject]()
OR
var stringDict: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
Dictionary of Array of String
var stringDict: [String: [String]] = [String: [String]]()
OR
var stringDict: Dictionary<String, Array<String>> = Dictionary<String, Array<String>>()
Array of Dictionaries of String
var stringDict: [[String: String]] = [[String: String]]()
OR
var stringDict: Array<Dictionary<String, String>> = Array<Dictionary<String, String>>()
Swift:
var myDictionary = Dictionary<String, AnyObject>()
I'm playing with this too. It seems strange that you can just declare an empty dictionary and then add a key/value pair to it like so :
var emptyDictionary = Dictionary<String, Float>()
var flexDictionary = [:]
emptyDictionary["brian"] = 4.5
flexDictionary["key"] = "value" // ERROR : cannot assign to the result of this expression
But you can create a Dictionary that accepts different value types by using the "Any" type like so :
var emptyDictionary = Dictionary<String, Any>()
emptyDictionary["brian"] = 4.5
emptyDictionary["mike"] = "hello"
You need to explicitly tell the data type or the type can be inferred when you declare anything in Swift.
Swift 3
The sample below declare a dictionary with key as a Int type and the value as a String type.
Method 1: Initializer
let dic = Dictionary<Int, String>()
Method 2: Shorthand Syntax
let dic = [Int:String]()
Method 3: Dictionary Literal
var dic = [1: "Sample"]
// dic has NOT to be a constant
dic.removeAll()
If you want to create a generic dictionary with any type
var dictionaryData = [AnyHashable:Any]()
Swift 4
let dicc = NSDictionary()
//MARK: - This is empty dictionary
let dic = ["":""]
//MARK:- This is variable dic means if you want to put variable
let dic2 = ["":"", "":"", "":""]
//MARK:- Variable example
let dic3 = ["name":"Shakeel Ahmed", "imageurl":"https://abc?abc.abc/etc", "address":"Rawalpindi Pakistan"]
//MARK: - This is 2nd Variable Example dictionary
let dic4 = ["name": variablename, "city": variablecity, "zip": variablezip]
//MARK:- Dictionary String with Any Object
var dic5a = [String: String]()
//MARK:- Put values in dic
var dic5a = ["key1": "value", "key2":"value2", "key3":"value3"]
var dic5b = [String:AnyObject]()
dic5b = ["name": fullname, "imageurl": imgurl, "language": imgurl] as [String : AnyObject]
or
//MARK:- Dictionary String with Any Object
let dic5 = ["name": fullname, "imageurl": imgurl, "language": imgurl] as [String : AnyObject]
//MARK:- More Easy Way
let dic6a = NSDictionary()
let dic6b = NSMutalbeDictionary()
To create an empty dictionary with the [:] aka the empty dictionary literal, you actually need to provide the context first as in the type of both the key and the value. The correct way to use the [:] to create an empty dictionary is:
var dict: [String: Int] = [:]
I'm usually using
var dictionary:[String:String] = [:]
dictionary.removeAll()
You can declare it as nil with the following:
var assoc : [String:String]
Then nice thing is you've already typeset (notice I used var and not let, think of these as mutable and immutable). Then you can fill it later:
assoc = ["key1" : "things", "key2" : "stuff"]
You can use the following code:
var d1 = Dictionary<Int, Int>()
var d2 = [Int: Int]()
var d3: Dictionary<Int, Int> = [Int : Int]()
var d4: [Int : Int] = [:]
var dictList = String:String for dictionary in swift
var arrSectionTitle = String for array in swift
var parking = [Dictionary < String, Double >()]
^ this adds a dictionary for a [string:double] input
It is very handy for finding your way
var dict:Dictionary = [:]