Getting Key from Dict as String in Swift - swift

New to coding here.
I have a dict with strings as keys and arrays of integers as values and I'm trying to get, from a given key, the String of that key. Not the value of the key, but the key itself. Now, I would just put an extra String into the array and call that, but my Xcode seems to have a bug where it really doesn't like having mixed type arrays and it doesn't work.
An example looks like this:
var allDict: [String: [Int]] = [:];
allDict.updateValue([1, 2, 3], forKey: "BAGEL"]);
allDict.updateValue([4, 5, 6], forKey: "DONUT"]);
allDict.updateValue([7, 8, 9], forKey: "MACARON"]);
I can get the values of each array quite fine with allDict["DONUT"]![1] //prints 5 for example, but what I want is to get the String of the key.
i.e. I would like to print DONUT using allDict["DONUT"]!
Is this possible? Thank you in advance!

It looks like you know your keys going in, in this example.
Here are a few ways you might recover your keys in a useful way, though:
Say you have a dictionary
var dict: [String: Int] = ...
You could get the array of keys:
let keys = dict.keys // keys is of type [String]
You can iterate over keys and values:
for (key, value) in dict {
...
}
You can merge dictionaries of and choose values from either dictionary when keys collide:
let mergedDict = dict.merge(otherDict) { leftValue, rightValue in
return leftValue
}
Addressing a version of your original question briefly:
Say you have the value for a certain key:
let donutValue = dict["DONUT"]
and somewhere else, where you lo longer have access to the key, you want to recover it from the value somehow. The best you could do is attempt to find the key by searching through the dictionary with the value you have.
var searchResult = dict.first { key, value in
return value == donutValue
}
This assumes the values in your dictionary are Equatable. Otherwise, you have to write some function or logic to figure out whether or not you've found that value in the dictionary corresponding to donutValue.

Related

Sort dictionary of type [String:any]

Frankly speaking, When I try to do filtering for the dictionary with the following key and value pair ["deviceId":21,"geofenceId":34], it's order get changed randomly. But, As a matter of fact, I want to be in the same order the whole time. How to do that with the same [String:Any] type.
Dictionary collection is unordered, but you can sort the keys though
let myDict = ["geofenceId":34, "deviceId": 1]
let sortedKeys = myDict.keys.sorted(by: { $0 < $1 })
print(sortedKeys)
Now you can loop through the sorted keys and access the item from dictionary.

accessing keys from a returned sorted array of dictionaries in Swift 4

I have an array of dictionaries called groupedDictionary defined below:
// The type is [String : [SingleRepository]]
let groupedDictionary = Dictionary(grouping: finalArrayUnwrapped) { (object) -> String in
var language = "Not Known to GitHub"
if let languageUnwrapped = object.language {
language = languageUnwrapped
}
return language
}
I can easily get all the keys as follows:
let keys = groupedDictionary.keys
However, when I try to sort this array using sorted(by:) in Swift 4, I successfully get the sorted array back with the type [(key: String, value: [SingleRepository])].
// the type is [(key: String, value: [SingleRepository])]
let sortedGroupedDictionary = groupedDictionary.sorted(by: { ($0.value.count) > ($1.value.count) })
How can I get all of the keys from sortedGroupedDictionary?
It is not possible to call ".keys" on sortedGroupedDictionary, since it has a different type.
Please note: I'm not trying to sort the array based on the keys. I did sort the array that consists of dictionaries, based on a predicate which is size of the array containing each value, now I just want to extract the keys.
The method Dictionary.sorted(by:) returns the keys and values of your original dictionary as an array of key-value pairs, sorted by the predicate you pass as an argument. That means that the first element of each tuple is the key you're looking for.
You can go through the result like this:
for (key, value) in sortedGroupedDictionary {
// handle this key-value-pair
}
If all you need is an array of the sorted keys, you can get that using
sortedGroupedDictionary.map { $0.key }

how to add multiple key value pairs to dictionary Swift

okay, i'm trying to have the user add a key and value pair to a dictionary i created and have it show up in a table view. i do that just fine but i cant seem to figure out how to add another pair. when i go to add another it replaces the last one. id really like to have multiple pairs. can someone help please?
heres my code:
//declaring the dictionary
var cart = [String:String]()
//attempting to add to dictionary
cart[pizzaNameLabel.text!] = formatter.stringFromNumber(total)
This is how dictionary works:
In computer science, an associative array, map, symbol table, or
dictionary is an abstract data type composed of a collection of (key,
value) pairs, such that each possible key appears at most once in the
collection.
So
var cart = [String:String]()
cart["key"] = "one"
cart["key"] = "two"
print(cart)
will print only "key" - "two" part. It seems that you may need an array of tuples instead:
var cart = [(String, String)]()
cart.append(("key", "one"))
cart.append(("key", "two"))
print(cart)
will print both pairs.
From Swift 5.0, you can use KeyValuePairs like ordered dictionary type with multiple keys.
See this Apple Document of KeyValuePairs. ;)
let recordTimes: KeyValuePairs = ["Florence Griffith-Joyner": 10.49,
"Evelyn Ashford": 10.76,
"Evelyn Ashford": 10.79,
"Marlies Gohr": 10.81]
print(recordTimes.first!)

Swift: dictionary access via index

I want to use values from a dictionary in my UITableViewCells. Can I get those from a dictionary by using indexPath.row for the value and indexPath.section for the key?
you can get the keys array and get the key at indexPath.section like this:
Array(yourDictionary.keys)[indexPath.section]
and you can get the value at indexPath.row from the values array like this:
Array(yourDictionary.values)[indexPath.row]
Edit:
if you want to get the values of a specific section key you should write:
let key = Array(yourDictionary.keys)[indexPath.section]
let array = yourDictionary[key]
let value = array[indexPath.row]
Dictionaries are inherently unordered. If you use dictionary.keys, you can get an array of keys and use that, as #Firas says in his/her answer, but there's no guarantee that next time you fetch an array of keys they will be in the same order.
Another option would be to use Int as the key type, then use the indexPath.row as the key.
It's really better to use an array as a data source for a table view.
If you want to store the values for a sectioned table view in a dictionary you should use an outer section array, which contains an inner row array, which contains a dictionary of values for the cell.
You can use:
Array(yourDictionary)[indexPath.row].key // or .value
Here is my small trick to access Dictionary by index. Just wrap dictionary!
var dict = [String: [Int]]()
dict.updateValue([1, 2, 3], forKey: "firstKey")
dict.updateValue([3, 4, 5], forKey: "secondKey")
var keyIndex = ["firstKey": "firstKey", "secondKey": "secondKey"]
var arr = [[String: [Int]]]()
for (key, value) in dict {
arr.append([keyIndex[key]!: value])
}
print(arr[0]) // ["firstKey": [1, 2, 3]]

Swift filter function

I am trying to remove null value for key in dictionary
so I have this kind of data:
let dic = ["FirstName": "Anvar", "LastName": "Azizov", "Website": NSNull(),"About": NSNull()]
let array = [dic,2,3,4]
let jsonResult:[String: AnyObject] = ["FirstName": "Anvar", "LastName": "Azizov", "Website": array,"About": NSNull()]
let jsonCleanDictionary = filter(jsonResult, {!($0.1 is NSNull)})
can not understand syntax of above filter function
Do not use NSNull() in swift instead prefer using nil. Further, since its a dictionary adding keys with a null value is pretty useless since dictionaries will return nil if the key doesn't exist. So when checking for null all you have to do is
if let some = dic["key"] as? Value {
// some now contains the value inside dic's key as a value type of Value.
}
Also the filter function works by taking a block which returns a bool so:
dict.filter { (key, value) -> Bool in
// Do stuff to check key and value and return a
// bool which is true if you want that key, value pair to
// appear in the filtered result.
}
In swift closure arguments can get anonymous names if not explicitly return. These names are of the format $0, $1, etc. Now, the filter function takes only parameter specifically the Self.Generator.Element from the CollectionType protocol. For dictionaries this is a tuple containing the key and the value. To access members of unnamed tuples you use .0, .1, .2, etc. depending on the index of the tuple member. So for dictionaries Self.Generator.Element is a tuple containing the key and the value. So $0.1 refers to the value of the key,value pair. Hope this clears this weird syntax up a little bit.