Retrieve Parse Array of Objects in Swift - swift

I'm storying an array of JavaScript key/value objects in a column of type Array on Parse like this:
[{"1432747073241":1.1},{"1432142558000":3.7}]
When I retrieve that column in Swift, I can see the data, but I'm unsure what data type to cast it as:
if let data = dashboardObject[graphColumn] as? [AnyObject]{
for pair in data{
println(pair)
}
}
That print yields this in the console (for the first pair):
{
1432747073241 = "1.1";
}
I can't seem to cast its contents as a Dictionary [Int:Double] and I'm guessing that means this is a string.
How do I parse this data in Swift? Thanks.

The Dictionary you should parse it to is [String: AnyObject]. It seems as if the keys of this dictionary are timestamps which you probably don't know. You could iterate through the dictionary like this:
for (key, value) in pair {
// do what you want in here with the value and/or the key
}

Related

Swift: Dictionary of Dicitionaries, cannot get subscript

I've looked at other subscript issues here and I don't think they match my problem. I have a dictionary of dictionaries - Dictionary[String:Dictionary[String:String]]
In an extension I want to loop through all the values (Dictionary[String:String] and retrieve one of the values.
So I wrote this:
for dictNEO in Array(self.values) {
print(dictNEO)
print(type(of: dictNEO))
print(dictNEO["approachDate"])
}
and am getting this error on the last print line: Value of type 'Value' has no subscripts
Here's the first two print lines:
["nominalDist": "\"13.58 ", "approachDate": "\"2020-Feb-01 08:18 ± < 00:01\"", "minimumDist": "\"13.58 ", "diameter": "\"92 m - 210 m\"", "name": "\"(2017 AE5)\""]
Dictionary<String, String>
So I am confused as to why it is telling me it has no subscripts when it sees the type of as a Dictionary.
You have written this as an extension to Dictionary if I understand you correctly and that means that self is generic and defined as Dictionary<Key, Value> and not to you specific type so in your for loop you are looping over an array of [Value].
So you need to typecast Value before accessing it as a dictionary
if let dictionary = dictNEO as? [String: String] {
print(dictNEO["approachDate"])
}
but since it makes little sense to have an extension to Dictionary where you access a specific key it would be better to write it as a function. Since the dictionary is well defined now there is no issue with the last print
func printValuesForSubKey(_ key: String, _ dict: [String: [String: String]]) {
for (dictNEO) in dict.values {
print(dictNEO)
print(type(of: dictNEO))
print(dictNEO[key])
}
}
Note, I don't have an explanation why type(of:) recognises it as [String: String]
The code snippet doesn't work because values property is a collection of collections and with Array(values) you create a collection of collection of collections. In short, instead going down the code goes up and creates new collection level.
Solution with a Higher order function map:
self.values.map { print(type(of: $0)); $0["approachDate"] }
Solution with For-In Loop
for dictNEO in self.values {
print(dictNEO)
print(type(of: dictNEO))
print(dictNEO["approachDate"])
}

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 }

Accessing values in a dictionary containing AnyObject

I have some data I stored into a dictionary which is defined as:
let data = Dictionary<String, AnyObject>()
In this dictionary the value is always a string, but the value can be an array or integer or string. But when I try to access an item in a array in this dictionary, like:
let item = data["key"][0]
It gives me this error:
Cannot subscript value of type "AnyObject"
How should I access that item?
You need to tell the compiler that you're expecting an array:
if let array = data["key"] as? [Int] {
let item = array[0]
}
Without that, the compiler only knows that there MAY be an AnyObject in data["key"] (it might also be nil).

Swift 3: Only continue processing Dictionary value if it's of type Array

I am receiving a data structure over the wire that's of type [String: AnyObject]. The reason for AnyObject is simply because the value can be of type Array or Dictionary. My condition is straight forward:
if let data = list["foo"], data.count > 0 {
// do stuff
}
My problem is, I only want that condition to pass if data is an Array. The condition I have fails because count property seems to work on a Dictionary as well (It probably counts the number of keys in the dictionary).
What's the best way to handle this?
You can cast data as an Array in your if statement:
if let data = list["foo"] as? [Any], data.count > 0 {
// do stuff
}
This will make sure that data is an Array before doing any operations on it.

Swift import dictionary to tableviewcell

I am trying to create a table view to show the content of a dictionary called tableText<String, String>. But in the cellForRowAtInSection method, when I do something like
let obj = tableText[indexPath.row]
It gives me a error saying that
cannot subscript a value of type 'Dictionary<String, String> with an index of Int.
I also tried things like
let obj = tableText[indexPath.row] as? NSDictionary
but the error is still there.
Could you help me with this please?
If you just want the values, you can get an array of values from the dictionary and used the indexPath.row on that array.
if let text = tableText.values[indexPath.row] as? String {
cell.textLabel.text = text
}
Obviously if you need them to be sorted you would have to sort them as dictionary is not sorted based on keys.
If you wanted them sorted alphabetically, you could do this
let sortedText = tableText.values.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
And use this sortedText array as your datasource