PFObject Array Sort - arrays

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 {

Related

How to store multiple datas in an Array in swift 4?

I am getting a JSON from an API. So, I want to store a particular value with key SKU. So, what I did was:
var skuArr = [""]
{ (response, error) in
if (error != nil)
{
print("Error \(error.debugDescription)")
}
else
{
self.coinsArr = response.arrayObject as? Array<Dictionary<String, Any>>
for i in 0 ..< (self.coinsArr?.count)!
{
self.skuArr = [response[i]["sku"].rawValue as! String]
}
}
So, with this I am getting the array in skuArr, but when i is 0 I am getting ["a"], and when i is 1 I want it to be ["a","b"], but it gives ["b"] only and when the loop ends with only the last value and not with ["a","b","c","d"] which I want as the final result. How can I insert each of them in the Array?
First of all declare skuArr as empty string array.
var skuArr = [String]()
And this is Swift. There are better ways than ugly index based loops to extract data for example with map or compactMap
if let result = response.arrayObject as? Array<Dictionary<String, Any>> {
self.coinsArr = result
self.skuArr = result.compactMap{ $0["sku"] as? String }
}
And why is coinsArr declared as optional as you are going to force unwrap it anyway? It's highly recommended to use non-optional types as much as possible. Non-optionals can never cause a well-liked unexpected found nil crash
Don't use this:
self.skuArr = [response[i]["sku"].rawValue as! String]
As this will replace the previous value with new one.
Use .append to insert into array.
self.skuArr.append([response[i]["sku"].rawValue as! String])
EDIT
change your initialisation as below:
skuArr: [String] = []

Swift Can't access Single object array

I am trying to access data from a json file. The problem is that some of the values are NSSingleObjectArrays (Arrays with only item) which I can't turn into strings.
class CarObject {
var pictureURL: String!
var carURL: String!
var carPrice: String!
required init(json: [String: AnyObject]) {
pictureURL = json["galleryURL"] as! String
carURL = json["viewItemURL"] as! String
carPrice = json["currentPrice"] as! String
}
}
I get the following error message:
Could not cast value of type '__NSSingleObjectArrayI' (0x10a2ec548) to 'NSString' (0x109729440).
I tried to access them like this:
"json["galleryURL"][0] as String!"
but I get the following error:
Type 'Any?' has no subscript members
The values look like this:
galleryURL = ("one value");
Do you guys know a way how to access them easily?
Thanks!
Just cast things to the appropriate types first. It sounds like your values are arrays containing a single string, so something like this:
var pictureURL: URL
required init?(json: [String: AnyObject]) {
guard let pictureURLString = (json["galleryURL"] as? [String])?.first,
let pictureURL = URLComponents(string: pictureURLString)?.url else {
return nil
}
self.pictureURL = pictureURL
}
Also, you may want to reconsider the types you're using for your properties. The pictureURL and carURL properties are URLs, so they make more sense typed as URL. The carPrice property is likely numeric, so it makes more sense as a Double.

Filtering Array but keeping the indexPath position

I am using a UISearchController in my updateSearchResultsForSearchController
I am filtering an array of usernames with a NSPredicate:
self.filteredChats.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.gruppenNamen as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredChats = array as! [String]
Is there a way to store the indexPath of each filtered element?
I need to know that in order to display my cells correctly, since I am also using arrays for images and other data.
Let's says that you have gruppenNamen and gruppenImages. You want to keep them synchronized.
I would strongly suggest that you create a custom class with a property name, and a property image.
Since you seem to not want that, you could use indexesOfObjectsPassingTest: and objectsAtIndexes:. I don't use Swift, so I'll code in Objective-C, but it should be easily translated.
NSIndexSet *indexes = [self.gruppenNamen indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [(NSString *)obj rangeOfString:searchController.searchBar.text options:NSCaseInsensitiveSearch].location != NSNotFound;
}];
self.filteredChat = [self. gruppenNamen objectsAtIndexes:indexes];
self.filteredImages = [self.gruppenImages objectsAtIndexes:indexes];
I used rangeOfString:options for the equivalent of contains[c] of your predicate. You could use a NSPredicate here too.

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.

cast dictionary elements of different types

I am using such code to get JSON from server:
var jsonresult = NSArray()
do {
jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
}
It helps me to get an array of dictionaries in jsonresult variable.
Then I am looping through array to add all dictionaries to another array.
for i in jsonresult {
print(i)
self.otherArray.append(i as! Dictionary<String, AnyObject>)
}
I am using Dictionary type because there are strings values as well as Double values.
Problem is that after data is inserted I can not use "double" values. I get such error: Could not cast value of type 'NSTaggedPointerString' (0x10c472860) to 'NSNumber'
Yes, I know that I can use (value as! NSString).doubleValue but it would be better to cast NSTaggedPointerString into NSNumber in the begining.
Any ideas how can I do it? Maybe I can cast each element of dictionary while adding them to self.otherArray?

Resources