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

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)
}

Related

Hot to declare an empty Map/dictionary?

I would like to initialize a recursive function with a Map. To declare a read-only dictionary with value we can do:
let dictionary1 = dict [ (1, "a"); (2, "b"); (3, "c") ]
Try it online!
Now, I would like to create an empty dictionary. How to achieve that?
I am looking fo something like:
let dictionary1 = {} // <- ok this is js
let (stuff, dictionary2) = parseRec("whatever", dictionary1)
You can do:
let dictionary1 = dict []
for elem in dictionary1 do
printfn "Key: %d Value: %s" elem.Key elem.Value
and that gives you an empty dictionary.
The printfn usage reveals to the type inference engine the correct types of key and value.
If you want to be explicit then you can specify the types in several ways:
let dictionary1 = dict Seq.empty<int * string>
let dictionary1 = dict ([] : (int * string) list)
let dictionary1 = dict [] : System.Collections.Generic.IDictionary<int, string>
let dictionary1 : System.Collections.Generic.IDictionary<int, string> = dict []
Since you ask for Map/Dictionary, here is two other solutions for Map:
let dictionary1 : Map<int, string> = Map.empty
let dictionary1 = Map<int, string> []
source
If you need a .NET Dictionary, you can use a .net Dictionary:
let dictionary1 = new System.Collections.Generic.Dictionary<int, string>()

Swift: Get all key value pairs from a String

I have a String which has many key value pairs appended by a & sign. i.e: params = key1=Hello&key2=Hello World&key3=Hi Hello
Is there a way to extract the values just by passing the keys present in the string? For example I want to extract the value of key1, key2, key3.
let string = "key1=Hello&key2=Hello World&key3=Hi Hello"
let components = string.components(separatedBy: "&")
var dictionary: [String : String] = [:]
for component in components{
let pair = component.components(separatedBy: "=")
dictionary[pair[0]] = pair[1]
}
And in dictionary you will get your key-value pairs.
You can use URLComponents and URLQueryItem anyway by creating a dummy URL
let params = "key1=Hello&key2=Hello World&key3=Hi Hello"
if let components = URLComponents(string: "http://dummy.com/path?" + params.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!),
let queryItems = components.queryItems {
let arrayOfValues = queryItems.flatMap{ $0.value }
print(arrayOfValues)
}
see also Best way to parse URL string to get values for keys?
let params = "key1=Hello&key2=Hello World&key3=Hi Hello"
let sepparated = params.components(separatedBy: CharacterSet(charactersIn: "&="))
let keys = sepparated.enumerated().filter{$0.0 % 2 == 0}
print (keys) // [(offset: 0, element: "key1"), (offset: 2, element: "key2"), (offset: 4, element: "key3")]

What is the best way to fetch multi-level dictionary information in Swift 3

I have a Dictionary of format
myDict: Dictionary <String, Dictionary>
For example,
“AUTOID-1” {
“key1” : “val1_1”,
“key2” : “val2_1:
},
“AUTOID-2” {
“key1” : “val1_2”,
“key2” : “val2_2:
},
“AUTOID-3” {
“key1” : “val1_3”,
“key2” : “val2_3:
}
For this entire dataset, I want to find out value of AUTOID corresponding to highest and lowest value of key2
Using
myKeyData = myDict.allKeys
I can get an array of all AUTOID and then I can use below for further processing:
for index in 0...myKeyData.count-1 {
if let insideDict = myDict[myKeyData[index]] as? NSDictionary {
// FURTHER PROCESSING
}
}
Is there a better way to achieve the objective of finding AUTOID corresponding to highest and lowest value of key2
I would use map to get an array of tuples containing keys ("AUTOID-N") and values ("valX_Y"), and then get the min and max of that array according to a comparator that compares the values only.
let myDict = ["AUTOID-1": ["key1" : "val1_1", "key2" : "val2_1"],
"AUTOID-2": ["key1" : "val1_2", "key2" : "val2_2"],
"AUTOID-3": ["key1" : "val1_3", "key2" : "val2_3"]]
let key2Values = myDict.map{ key, value in (key: key, value: value["key2"]!) }
let minKey = key2Values.min(by: {$0.value < $1.value})?.key
let maxKey = key2Values.max(by: {$0.value < $1.value})?.key
print(minKey, maxKey)
Use reduce:
let myDict = ["AUTOID-1": ["key1" : "val1_1", "key2" : "val2_1"],
"AUTOID-2": ["key1" : "val1_2", "key2" : "val2_2"],
"AUTOID-3": ["key1" : "val1_3", "key2" : "val2_3"]]
let initalElement = (min: myDict.first!, max: myDict.first!)
let result = myDict.reduce(initalElement) { (aggregate, element) in
guard let minValue = aggregate.min.value["key2"],
let maxValue = aggregate.max.value["key2"],
let currentValue = element.value["key2"] else {
return aggregate
}
let newMin = currentValue < minValue ? element : aggregate.min
let newMax = currentValue > maxValue ? element : aggregate.max
return (min: newMin, max: newMax)
}
print(result.min)
print(result.max)
This assume myDict is non-empty. You basically choose the first element of myDict to start the reduce loop and compare it with the rest of the key-value pairs in myDict.

Convert String Array to JSON or 2D Array SWIFT

I currently have a NSMutableArray "localArray" and I am trying to create that into a JSON Array or a 2D Array. I get this data my creating a database and running a query using a for loop on the database.
{
Food,
Burger,
3.99,
1.25,
POP,
Crush,
1.99,
.89,
and more.
}
The reason why I am looking for a JSON or 2d Array is I want to hold the data in the localArray in such a way that I can identify by type and then do something like .valueForKey("Name") or .valurForKey("Price") and add that to my tableview's cell text label or labels.
{
{
Type Food,
Name Burger,
Price 3.99,
Cost 1.25,
},
{
Type POP,
Name Crush,
Price 1.99,
Cost .89,
},
and more
}
I have already tried JSONSerialization, but that failed and also tried 2d Array but no luck.
Any help will be highly appreciated.
This is how I Query and add the data to localArray
let queryType = data.select(ada, code, name, proof, size, case_size, price)
.filter(bevType == type)
let rows = Array(queryType)
for row in rows{
let name = row[self.name]
let type = row[self.type]
let cost = row[self.cost]
let price = row[self.price]
localArray.addObject(name)
localArray.addObject(type)
localArray.addObject(cost)
localArray.addObject(price)
}
I solved it myself by creating a dictionary.
for row in rows{
var rDict: Dictionary = [String: String]()
rDict["Name"] = row[self.name]
rDict["Type"] = row[self.type]
rDict["Cost"] = row[self.cost]
rDict["Price"] = row[self.price]
localArray.addObject(rDict)
}
If fields are always repeating in count of 4, you can try doing this:
var array = [[String: AnyObject]]()
for var i = 0 ; i < array.count ; i += 4 {
var k = 0
var dict = [String: AnyObject]
dict["Type"] = array[i + k++]
dict["Name"] = array[i + k++]
dict["Price"] = array[i + k++]
dict["Cost"] = array[i + k]
array.append(dict)
}
Then extract dictionary from this swift array and use same keys to extract data from dictionary to be used in your cell like
let dict = array[indexPath.row]
cell.title = dict["Name"]

How to unwrap NSMutableDictionary.allkeys in optional String Array

I am trying to get all the key values of NSMutableDictionary as String Array. I am using this myNSMutableDictionary.allkeys to get the values as an Array but I cannot find a way to unwrap the key values.
This is what I have tried so far:
for (key, _) in NSMutableDictionary {
println("THIS IS MY NEW KEY\(key)")
}
And I tried this
var myArray:NSArray = myNSMutableDictionary.allKeys
var string:NSString? = uniqueIDArray[0] as? NSString
println("This is unwraped value\(string!)")
And this
var myArray:Array = myNSMutableDictionary.allKeys
println("This is unwraped value\(myArray[0])")
I keep getting the value as Optional("kMSZgoTmiX") instead of kMSZgoTmiX which is the key value I need
Thank you for all your help!
So you've got a dictionary with values that are strings (and keys that are something, assume String):
var dictionaryOfStringValues : [String:String] = /* your dictionary */
And you want to iterate over the contents:
for (key, val) in dictionaryOfStringValues {
// use key and val
}
If you just want the values in a way you can easily iterate over:
var theValues = dictionaryOfStringValues.values
If you insist that theValues be an Array:
var theValuesAsAnArray = Array(dictionaryOfStringValues.values)
If you are starting with an NSMutableDictionary, then convert it at the point where it FIRST ENTERS your Swift code into a Swift Dictionary. Use an as variant to do that. After that, pure Swift.
Like this:
7> for (key, value) in ["a":1, "b":2] {
8. println (key)
9. println (value)
10. }
b
2
a
1
let myNSMutableDictionary = NSMutableDictionary()
myNSMutableDictionary["myKey1"] = 5
myNSMutableDictionary["myKey2"] = 10
myNSMutableDictionary["myKey3"] = 15
let myKeysArrayUnsorted = myNSMutableDictionary.allKeys as [String]
let myValuesArrayUnsorted = myNSMutableDictionary.allValues as [Int]
let keyString = myKeysArrayUnsorted[0] // "myKey2"
let keyValue = myNSMutableDictionary[keyString] as Int // 10
println("This is my first unsorted key \(keyString) = \(keyValue)")
let myKeysArraySorted = (myNSMutableDictionary.allKeys as [String]).sorted(<)
for key in myKeysArraySorted {
println(myNSMutableDictionary[key]!) // 5 10 15
}

Resources