How to combine two complex Dictionaries - ios

I'm curious how to combine two dictionaries which one of them contains key with array or another dictionary as value.
for simple combining e.g.
var dict1 = ["bbb":"dict1",
"her": "dict1"]
let dict2 = ["aaa":"dict2",
"her": "doct2",
"bob": "doct2"]
dict1 += dict2 // result is as I expected
func += <K, V> (inout left: [K:V], right: [K:V]) {
for (k, v) in right {
left.updateValue(v, forKey: k)
}
}
But problem rise when I want to combine more complex dictionary e.g.
var dict1 = ["bbb":"dict1",
"her": "dict1"]
let complexDict2 = ["aaa":"dict2",
"her": "dict2",
"arr": ["one", "two"]]
dict1 += complexDict2 // in here method which override '+=' operator for dictionaries does not work anymore...
My question is whether you guys have a proved way to combine more complex dictionaries?
Upadate
My expected result from combining dict1 and complexDict2 is :
let resultDict = ["aaa":"dict1",
"aaa":"dict2",
"her": "dict2",
"arr": ["one", "two"]]

The issue here lies in the types of dict1 and complexDict2.
dict1 is inferred to have type [String : String], whereas complexDict2 is inferred to have type [String : Any].
Your code works just fine, if you explicitly specify a type annotation on dict1:
var dict1: [String : Any] = [
"aaa":"dict1",
"her": "dict1"
]

Related

can i sum of values that has the same key in dictionary

I have a dictionary like this :
let dic: KeyValuePairs = ["foo":2,"bar":3,"bat":5, "foo":5,"bat":7,"bar":5]
I want the sum of values that has the same key.
The output should look like this:
["foo":7, "bar":8, "bat":12]
KeyValuePairs responds to reduce so you can do this
let dic: KeyValuePairs = ["foo":2,"bar":3,"bat":5, "foo":5,"bat":7,"bar":5]
let result : [String:Int] = dic.reduce(into: [:]) { (current, new) in
current[new.key] = new.value + (current[new.key] ?? 0)
}

Append value into [[String: String]]()

I'm trying to add value into [[String: String]]() as follow:
let realm = try! Realm()
let nrcObj = realm.objects(ObjectNRC.self)
for nrc in nrcObj {
nrcTownshipCode["value"] = nrc.regionCode
nrcTownshipCode["display"] = nrc.regionCode
}
But when I did like that, I've encountered following error message.
Cannot subscript a value of type '[[String : String]]' with an index
of type 'String'
Please suggest me how to do it. Thanks.
What are you trying to do is to treat [[String: String]] as dictionary which is not! Actually, [[String: String]] is an array of dictionaries ([String: String]). So what would you need to do instead -for instance-:
for nrc in nrcObj {
nrcTownshipCode[0]["value"] = nrc.regionCode
nrcTownshipCode[0]["display"] = nrc.regionCode
}
means that you would iterate through nrcObj and append values for the first dictionary in your array. Note that it might not be your desired result, but it describes your issue and how you could fix it. For instance, you might want to add an additional variable to hold the iteration count and use it as an index for your array:
var i = 0
for nrc in nrcObj {
nrcTownshipCode[i]["value"] = nrc.regionCode
nrcTownshipCode[i]["display"] = nrc.regionCode
i += 1
}

Swift: Could not cast value of type '__NSCFArray' to 'NSDictionary'

I have JSON data from website. I made the main dictionary and I can parse every data except one sub dictionary. I get the error "Swift: Could not cast value of type '__NSCFArray' to 'NSDictionary'"
This example of my data. I cannot parse "weather" but I can parse all other dictionaries like "wind".
["name": Mountain View, "id": 5375480, "weather": (
{
description = "sky is clear";
icon = 01n;
id = 800;
main = Clear;
}
), "base": cmc stations, "wind": {
deg = "129.502";
speed = "1.41";
Snippet of code
let windDictionary = mainDictionary["wind"] as! [String : AnyObject
let speed = windDictionary["speed"] as! Double
print(speed)
let weather = mainDictionary["weather"] as! [String : AnyObject]
print(weather)
on behalf your comment...I would say windDictionary is Dictionary...
Dictionary denotes in JSON with {} and
Array denotes with [] // In printed response you may have array with ()
So, your weather part is Array of Dictionary...You have to parse it like
let weather = mainDictionary["weather"] as! [[String : AnyObject]] // although please not use force unwrap .. either use `if let` or `guard` statement

How to convert dictionary to array

I want to convert my dictionary to an array, by showing each [String : Int] of the dictionary as a string in the array.
For example:
    
var myDict: [String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
    
I'm aware of myDict.keys.array and myDict.values.array, but I want them to show up in an array together. Here's what I mean:
    
var myDictConvertedToArray = ["attack 1", "defend 5", "block 12"]
You can use a for loop to iterate through the dictionary key/value pairs to construct your array:
var myDict: [String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
var arr = [String]()
for (key, value) in myDict {
arr.append("\(key) \(value)")
}
Note: Dictionaries are unordered, so the order of your array might not be what you expect.
In Swift 2 and later, this also can be done with map:
let arr = myDict.map { "\($0) \($1)" }
This can also be written as:
let arr = myDict.map { "\($0.key) \($0.value)" }
which is clearer if not as short.
The general case for creating an array out of ONLY VALUES of a dictionary in Swift 3 is (I assume it also works in older versions of swift):
let arrayFromDic = Array(dic.values.map{ $0 })
Example:
let dic = ["1":"a", "2":"b","3":"c"]
let ps = Array(dic.values.map{ $0 })
print("\(ps)")
for p in ps {
print("\(p)")
}
If you like concise code and prefer a functional approach, you can use the map method executed on the keys collection:
let array = Array(myDict.keys.map { "\($0) \(myDict[$0]!)" })
or, as suggested by #vacawama:
let array = myDict.keys.array.map { "\($0) \(myDict[$0]!)" }
which is functionally equivalent
With Swift 5
var myDict:[String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
let arrayValues = myDict.values.map({$0})
let arrayKeys = myDict.keys.map({$0})
You will have to go through and construct a new array yourself from the keys and the values.
Have a look at 's swift array documentation:
You can add a new item to the end of an array by calling the array’s
append(_:) method:
Try this:
var myDict:[String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
var dictArray: [String] = []
for (k, v) in myDict {
dictArray.append("\(k) \(v)")
}
Have a look at What's the cleanest way of applying map() to a dictionary in Swift? if you're using Swift 2.0:

How to append associative array elements in Swift

How do I create and append to an associative array in Swift? I would think it should be something like the following (note that some values are strings and others are numbers):
var myArray = []
var make = "chevy"
var year = 2008
var color = "red"
myArray.append("trackMake":make,"trackYear":year,"trackColor":color)
The goal is to be able to have an array full of results where I can make a call such as:
println(myArray[0]["trackMake"]) //and get chevy
println(myArray[0]["trackColor"]) //and get red
Simply like this:
myArray.append(["trackMake":make,"trackYear":year,"trackColor":color])
Add the brackets. This will make it a hash and append that to the array.
In such cases make (extensive) use of let:
let dict = ["trackMake":make,"trackYear":year,"trackColor":color]
myArray.append(dict)
The above assumes that your myArray has been declared as
var myArray = [[String:AnyObject]]()
so the compiler knows that it will take dictionary elements.
I accept above answer.It is good.Even you have given correct answer,I like to give simplest way.The following steps are useful,if you guys follow that.Also if someone new in swift and if they go through this,they can easily understand the steps.
STEP 1 : Declare and initialize the variables
var array = Array<AnyObject>()
var dict = Dictionary<String, AnyObject>()
var make = "chevy"
var year = 2008
var color = "red"
STEP 2 : Set the Dictionary(adding keys and Values)
dict["trackMake"] = make
dict["trackYear"] = year
dict["trackColor"] = color
println("the dict is-\(dict)")
STEP 3 : Append the Dictionary to Array
array.append(dict)
println("the array is-\(array)")
STEP 4 : Get Array values to variable(create the variable for getting value)
let getMakeValue = array[0]["trackMake"]
let getYearValue = array[0]["trackYear"]
let getColorValue = array[0]["trackColor"]
println("the getMakeValue is - \(getMakeValue)")
println("the getYearValue is - \(getYearValue)")
println("the getColorVlaue is - \(getColorValue)")
STEP 5: If you want to get values to string, do the following steps
var stringMakeValue:String = getMakeValue as String
var stringYearValue:String = ("\(getYearValue as Int)")
var stringColorValue:String = getColorValue as String
println("the stringMakeValue is - \(stringMakeValue)")
println("the stringYearValue is - \(stringYearValue)")
println("the stringColorValue is - \(stringColorValue)")
STEP 6 : Finally the total output values are
the dict is-[trackMake: chevy, trackColor: red, trackYear: 2008]
the array is-[{
trackColor = red;
trackMake = chevy;
trackYear = 2008;
}]
the getMakeValue is - Optional(chevy)
the getYearValue is - Optional(2008)
the getColorVlaue is - Optional(red)
the stringMakeValue is - chevy
the stringYearValue is - 2008
the stringColorValue is - red
Thank You
This sounds like you are wanting an array of objects that represent vehicles. You can either have an array of dictionaries or an array of vehicle objects.
Likely you will want to go with an object as Swift arrays and dictionaries must be typed. So your dictionary with string keys to values of differing types would end up having the type [String : Any] and you would be stuck casting back and forth. This would make your array of type [[String : Any ]].
Using an object you would just have an array of that type. Say your vehicle object's type is named Vehicle, that would make your array of type [Vehicle] and each array access would return an instance of that type.
If I want to try it with my own statement. Which also I want to extend my array with the data in my dictionary and print just the key from dictionary:
var myArray = ["Abdurrahman","Yomna"]
var myDic: [String: Any] = [
"ahmed": 23,
"amal": 33,
"fahdad": 88]
for index in 1...3 {
let dict: [String: Any] = [
"key": "new value"
]
// get existing items, or create new array if doesn't exist
var existingItems = myDic[myArray] as? [[String: Any]] ?? [[String: Any]]()
// append the item
existingItems.append(myArray)
// replace back into `data`
myDic[myArray] = existingItems
}

Resources