How to sort array of objects 'Any' based on key value in swift? - arrays

I have a NSAArray containing the objects any the object has the key & the value as issueDate:20230220100207
I am trying with this code but getting error:
let sortedArr = TicketsArr.sorted { $0["issueDate"] as? Int ?? .zero < $1["issueDate"] as? Int ?? .zero } as NSArray
I am getting this error with above code:
Instance method 'sorted(using:)' requires the types 'NSArray.Element' (aka 'Any') and '((_, _) -> Bool).Compared' be equivalent

Related

How to access value of array of dictionaries of dictionaries of array at index?

I have an array that holds dictionaries whose value is an array of dictionary whose value is an array of strings. Each key of each the dictionary is a String. the structure is like so:
[String : [String : [String]]]
I am trying to get the value of the array at the index like so:
for index in 0...arrayCount {
let thisValue = myArray[index]
}
where myArray represents the array of dictionaries in question.
However, I get the error message:
Cannot subscript a value of type '[String : [String : [String]]]' with an index of type 'Int'
I would think that saying let thisValue = myArray[index] would assign thisValue to be a dictionary of the form String : [String : [String]]
Can anyone explain I might be doing incorrectly and how I can access the value at index?
Your data type declaration:
[String: [String : [String]]]
Indicates that you have a Dictionary of Dictionaries with the final entries being arrays of strings.
So since all of your dictionaries uses String for keys, using a Int would indeed generate an error.
If you want to extract the Dictionary of arrays, you would need something similar to:
// let sourceData: [String: [String: [String]]] ...
guard
let myArrayOfDict: [String: [String]] = sourceData["some valid root key"],
let myArray: [String] = myArrayOfDict["Some other key"]
else { /* oops, those keys didn't match anything! */ return }
for index in 0..<myArray.count {
let thisValue = myArray[index]
}
for myString in myArray {
// myString is a "String"
}

Swift3 how do I get the value of a specific key in a string?

I've got a server response returning
(
{
agreementId = "token.virtual.4321";
city = AMSTERDAM;
displayCommonName = "bunch-of-alphanumeric";
displaySoftwareVersion = "qb2/ene/2.7.14";
houseNumber = 22;
postalCode = zip;
street = "";
}
)
how do I get the value of agreementId? response['agreementId'] is not working. i've tried some example code with .first but I cannot get it working.
Some extra information, I do a http call to a server with alamofire. I try to parse the json to a constant response:
let response = JSON as! NSDictionary
However that returns a error message
Could not cast value of type '__NSSingleObjectArrayI' (0x1083600) to 'NSDictionary' (0x108386c).
So now parse the json to an array, which seems to be working. The code above is what
let response = JSON as! NSArry
print(response)
spits out.
Now I only need to retrieve the value from the key "agreementId" and I have no clue how to do that.
In swift you need to use Swift's native type Array/[] and Dictionary/[:] instead of NSArray and NSDictionary, if you specify the type like above means more specific then the compiler won't complain. Also use optional wrapping with if let or guard let to prevent crash.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
if let dic = array.first {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}
Note: If you having more than one object in your array then you need to simply loop through the array to access each dictionary of array.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
for dic in array {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}

Swift force cast Bool to Int error when creating key/value pairs in dictionary

TLDR: Trying to create a dictionary with type [String]/[Any] with Key containing arrays of mixed data types. Then trying to loop through and create a new dict with just the Key and Bool Value results in a force cast error.
Thanks in advance for the help!
Long version:
I have 4 arrays I need to convert (2 String, 1 Bool, 1 Int) into a dictionary. I created a dictionary with the Key of type String and the Value of type Any as I need one of the String arrays to be the Key and the rest to be contained in an array as the Value. Like this:
var dict1: [String: [Any]] = [:]
Then I loop through the previously mentioned arrays and create key/value pairs:
Edit: i = 0
//i-1 to match iteration with array position
while i < dict1.count {
i += 1
dict1[stringArray1[i-1]] = [intArray[i-1], boolArray[i-1], stringArray2[i-1]]
}
When I print the dictionary, it contains the correct Key/Value pairs.
Now I need to create a dictionary with just the Key from dict1 and Bool array values from the key. So I've set up an empty array like this:
var dict2: [String: [Bool]] = [:]
and tried to create KeyValue pairs like this:
for (string, bool) in dict1 {
dict2[string] = bool
}
I get an error saying I need to force cast to type Bool. Force casting to type Bool creates an error saying swift can't convert an Int to a Bool. I tried changing the type of the Key in dict2 to type Int, and got an error saying to forecast to type Int. Doing so says Swift can't force Bool to Int.
EDIT:
this will help you with cast
var dict2: [String: [Bool]] = [:]
var dict1: [String: [Any]] = ["a" : [1], "b" : [true], "c": [false], "d" : ["e"]]
for (string, bool) in dict1 {
dict2[string] = bool.flatMap({$0 as? Bool})
}
This is an example how can you filter and cast [string:any] dictionary to [string:bool]
let dict: [String : Any] = ["a" : 1, "b" : true, "c": false]
let casted = dict.filter{$0.value is Bool}.reduce([String: Bool]()) { (dictionary, nextValue) -> [String: Bool] in
var mutableDictionary = dictionary
mutableDictionary[nextValue.key] = nextValue.value as? Bool
return mutableDictionary
}
I think there will be no problem for you to follow this and cast [String:[Any]] to [String:[Bool]]

How to check a value is inside nested dictionary swift

I have a problem concerning my nested dictionary.
var level1Dictionary = [String : [String : String]]()
var ChosenDeckLabel = [String]
textview.text
I want to see if the dictionary contains a certain value within my, else if statement as such:
else if level1Dictionary[ChosenDeckLabel[textview.text]] != nil {
this returns error:
Cannot subscript value of type String with an index of type String!
How should I cast it to check if the nested dictionary contains the value?
Dictionaries are optionals by default because they are not sure if a key/value pair exist. Be sure to include your "!" AND "?" to wrap and unwrap your data being passed.
Arrays offer subscripting via integers and ranges as seen in Swift's API:
public subscript (index: Int) -> Element
public subscript (subRange: Range<Int>) -> ArraySlice<Element>
You're trying to subscript via a string which is throwing the error. You need to get the index of the element in the array and then use that to subscript the array to get the value: e.g.
let dictOfDicts = [String : [String : String]]()
var arrayOfStrings: [String] = ["a", "b", "c"]
let stringToCheck = "a"
dictOfDicts["a"] = ["some": "thing"]
if let index = array.indexOf(stringToCheck) {
if dictOfDicts[array[Int(index)]] != nil {
// do something
}
}
I think this is what you intend to do:
else if level1Dictionary[strIndex1][strIndex2] != nil {
When you are doing this:
level1Dictionary[ChosenDeckLabel[textview.text]]
you are trying to access the ChosenDeckLabel array using a String subscript:
ChosenDeckLabel[textview.text]
which is not a valid operation. Arrays are Int indexed and not string indexed.

PFObject Array Sort

I'm using Parse and I have an array of PFObjects called "scorecardData". Each PFObject has a "score" property that is of type Int. I'm trying to sort my array by "score" but I'm getting the following error: "Binary operator '<' cannot be applied to two 'AnyObject?' operands". I'm not sure what I'm doing wrong here. I also tried down casting the objectForKey("score") as! Int but its not letting me do this. Any suggestions? Thanks in advance.
var scorecardData = [PFObject]()
scorecardData.sortInPlace({$0.objectForKey("score") < $1.objectForKey("score")})
You declared scorecardData variable as Array of PFObject. Why are you trying access PFObject property using objectForKey: reserved? Anyway I am not parse expert. But if you declared your array as [PFObject] you can use:
scorecardData.sortInPlace({$0.score < $1.score})
But this won't work unless you subclass PFObject for a more native object-oriented class structure. If you do that remember also to specify:
var scorecardData = [YOUR_NEW_CLASS]()
I strongly recommend subclassing PFObject to make use of all swift type-safe goodies.
But if you want to keep your data structure you can use:
scorecardData.sortInPlace({($0["score"] as! Int) < ($1["score"] as! Int)})
Keep in mind that it's dangerous, and in future avoid it.
If you want to Sort your array of PFOject... You can do this
extension Array where Element:PFObject {
func sort() -> [PFObject] {
return sort { (first, second) -> Bool in
let firstDate = first.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
let secondDate = second.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
return firstDate.compare(secondDate) == .OrderedAscending
}
}
}
Have you tried doing this?
var query = PFQuery(className:"ScoreCard")
// Sorts the results in ascending order by the score field
query.orderByDescending("score")
query.findObjectsInBackgroundWithBlock {

Resources