NSSortDescriptor evaluating ascending numbers (Swift)
Asked Answered
O

3

8

App has contentid coming in as a number string from a json file:

let contentid: AnyObject! = jsonFeed["contentid"]

let stream:Dictionary = [
   "contentId": contentid as! String,
]

It is later saved to [NSManagedObject] with:

var articles = [NSManagedObject]()

let entity =  NSEntityDescription.entityForName("Article", inManagedObjectContext: managedContext)
let article = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)

article.setValue(stream["contentId"], forKey: "contentid")

articles.append(article)

Finally, I use NSSortDescriptor to have Core Data return entries in numerical ascending order:

let sort = NSSortDescriptor(key: "contentid", ascending: true)
fetchRequest.sortDescriptors = [sort]

But entries 6 - 10 are returned as: 10, 6, 7, 8, 9. What would be the correct method of having these numbers evaluated correctly using NSSortDescriptor?

UPDATE:

For the Swift version, please see Volker's answer below. I ended up using:

let sort = NSSortDescriptor(key: "contentid", ascending: true, selector: "localizedStandardCompare:")

and it evaluated the numbered strings as true integers.

UPDATE: Swift 2:

Selector syntax has changed and no longer accepts objc pointers. Thank you user1828845.

let sort = NSSortDescriptor(key: "contentid", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:)))

Oliveolivegreen answered 13/5, 2015 at 12:58 Comment(8)
is contentid a number or a string internally?Moonfaced
@Moonfaced It is a string internally.Oliveolivegreen
Descriptor is treating these as numbers. Thats why it is showing 10 before 6. Possible solution is treat these numbers as NSString.Elsa
Please post more code for clarification.Elsa
@Volker, so I should convert the string to a Int32 and store it as such? Abdul Yasin was implying that it needs to be a String, no?Oliveolivegreen
while an Int32 will help you may also see the duplicate question that has another answer, that is more flexibel and maybe easier. should be easy to get that into Swift quickly.Moonfaced
There exists init(key:ascending:selector:) and there you can use selector: "localizedStandardCompare:"as described here for example nshipster.com/nssortdescriptorMoonfaced
@Volker, it worked perfectly. Thank you for the link as finding Swift code references are limited thus far. I went with: let sort = NSSortDescriptor(key: "contentid", ascending: true, selector: "localizedStandardCompare:")Oliveolivegreen
M
4

The values you want to sort are actually strings and not numbers, thus the strange sort order. For Swift there exist an initializer init(key:ascending:selector:) of NSSortDescriptorand thus you can use selector: "localizedStandardCompare:" as described for example at nshipster.com/nssortdescriptor

The localizedStandardCompare: gives you a Finder like sorting of string values in a way that numbers are sorted naturally as you would sort numbers. So 1,...,9,10,...,99, 100 etc.

Moonfaced answered 13/5, 2015 at 17:59 Comment(0)
C
7

In my case I tried it with

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "formId", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:))) Its working for me.

Creative answered 23/6, 2016 at 13:19 Comment(0)
M
4

The values you want to sort are actually strings and not numbers, thus the strange sort order. For Swift there exist an initializer init(key:ascending:selector:) of NSSortDescriptorand thus you can use selector: "localizedStandardCompare:" as described for example at nshipster.com/nssortdescriptor

The localizedStandardCompare: gives you a Finder like sorting of string values in a way that numbers are sorted naturally as you would sort numbers. So 1,...,9,10,...,99, 100 etc.

Moonfaced answered 13/5, 2015 at 17:59 Comment(0)
L
0
        let descriptor: NSSortDescriptor = NSSortDescriptor(key: "message_time", ascending: true)
        let sortedResults = arrayForMessages.sortedArray(using: [descriptor])
        print(sortedResults)
Lyle answered 1/9, 2017 at 10:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.