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 }
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 have a dictionary as [Int: Any]()
my code:
var test = [Int: Any]()
test = self.header_all_items[header] as! [Int : Any]
for tes in test{
for (key:value)in tes{ // error line
print(key)
}
}
I got this error :
type (key:Int, value: Any) does not conform to protocol sequence
Your code should be
var test = [[Int: Any]]()
//assign your header
for tes in test{
for (key, value) in tes{ // error line
print("\(key)")
}
}
So first of all:
You must have an array of dictionary and not just a dictionary: [[Int: Any]]
Change your last for to for (key, value) in tes
I guess you want to iterate over your dictionary, if so then below code may help you
let test = self.header_all_items[header] as! [Int : Any]
for (key, value) in test {
print("\(key)")
}
I want to set a value to a key in a computed property of type dictionary. I want to do something like this:
class Foo {
var dict: [String: String] {
dict["a"] = "b"
}
}
However that doesn't compile.
Cannot assign through subscript: 'dict' is a get-only property
I can do something like this but it's a bit verbose:
class Foo {
var values: [String: String] {
var tempValues = [String: String]()
tempValues["a"] = "b"
return tempValues
}
}
Is there a better way of doing this? For context, what I want to achieve is having dict by default to be an empty [String: String]() in a base class and when I override the property in a subclass I want to assign values to said dictionary.
The syntax
var dict: [String: String] {
dict["a"] = "b"
}
is the short form for
var dict: [String: String] {
get {
dict["a"] = "b"
}
}
which indicates a read-only property.
You need to add the setter
var dict: [String: String] {
get {
return [:]
}
set {
dict["a"] = "b"
}
}
But be careful, you can easily run into a infinite loop when you call the setter by itself (which it does in this example).
Actually this kind of computed property is only useful if you are going to map another value.
and when I override the property in a subclass I want to assign values to said dictionary.
Ehh... Just do it:
class A {
var dict: [String: String] {
return [:]
}
}
class B: A {
override var dict: [String : String] {
return ["Hello":"Hi"]
}
}
Did you forget the override keyword?
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 = [:]