I am working on an iOS app and I have data stored in CoreData that I am loading into a UITableView. The data entities have an attribute called id
which is a string
for swift 4.2
You can sort array using NSSortDescriptor
let descriptor: NSSortDescriptor = NSSortDescriptor(key: "lastMessageDate", ascending: false)
let sortedResults = arrChatDialogs?.sortedArray(using: [descriptor])
Swift 3
let sortDescriptor = NSSortDescriptor(key: "id", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare))
hope it helps
You can sort the collection of object with default sorted function as:
e.g. your array of object is like
data = [
{
name: "Naresh",
dept: "CSC",
id: 102
},
{
name: "Rahul",
dept: "CSC",
id: 101
},
{
name: "Amar",
dept: "CSC",
id: 100
}
]
//Comparing string key
let sortByName = data.sorted { (model1, model2) -> Bool in
return (model1.name.localizedCompare(model2.name) == ComparisonResult.orderedAscending)
}
/* The ComaprisonResult is default enum whose possible cases are: */
public enum ComparisonResult : Int {
case orderedAscending
case orderedSame
case orderedDescending
}
/*** SORTING ACCORDING TO NUMERICAL VALUE ***/
//Comparing digit key including Int, Double, Float & all
let sortByNumber = data.sorted { (model1, model2) -> Bool in
return model1.id < model2.id
}
//You can use the shot form of automatic closure as:
let sortByNumber = data.sorted { $0.id > $1.id }
//In the autoclosure the $0 represent first parameter, $1 represent second parameter. The return statement is optional if closure or functions contains only single statement.
Why to bother with obj-c style's NSSortDescriptor
, In swift we can nicely sort using Swift high order functions - xcode 8.x swift 3.x
class Person: NSObject {
let firstName: String
let lastName: String
let age: Int
init(firstName: String, lastName: String, age: Int) {
self.firstName = firstName
self.lastName = lastName
self.age = age
}
override var description: String {
return "\(firstName) \(lastName)"
}
}
let a = Person(firstName: "a", lastName: "b", age: 24)
let b = Person(firstName: "c", lastName: "d", age: 27)
let c = Person(firstName: "e", lastName: "f", age: 33)
let d = Person(firstName: "g", lastName: "h", age: 31)
let peopleObject = [d, b, a, c]
//SWIFTY
let sortedByFirstNameSwifty = peopleObject.sorted(by: { $0.firstName < $1.firstName })
print(sortedByFirstNameSwifty)//prints[a b, c d, e f, g h]
//Objective c way
let firstNameSortDescriptor = NSSortDescriptor(key: "firstName", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:)))
let sortedByFirstName = (peopleObject as NSArray).sortedArray(using: [firstNameSortDescriptor])
print(sortedByFirstName)//prints [a b, c d, e f, g h]
For Swift3
key is
result: Bool = 0 < "string1".localizedCompare("string2").rawValue
Use like this
[some string array].sorted { return 0 < "string1".localizedCompare("string2").rawValue }
Sort descriptors in a (SQLite-based) Core Data fetch request cannot use custom comparators and only a limited set of "built-in" comparison methods. This is documented in Fetch Predicates and Sort Descriptors in the "Core Data Programming Guide":
... The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work. The supported sort selectors are
compare:
andcaseInsensitiveCompare:
,localizedCompare:
,localizedCaseInsensitiveCompare:
, andlocalizedStandardCompare:
(the latter is Finder-like sorting, and what most people should use most of the time). In addition you cannot sort on transient properties using the SQLite store.
Fortunately, there is one that should fit your needs:
let sortDescriptor = NSSortDescriptor(key: "id", ascending: true,
selector: "localizedStandardCompare:")
localizedStandardCompare:
does a "Finder-like" comparison and
in particular treats digits within strings according to their
numerical value.
For Swift 2.2/Xcode 7.3 and later:
let sortDescriptor = NSSortDescriptor(key: "id", ascending: true
selector: #selector(NSString.localizedStandardCompare))