How do I sort a swift array containing instances of NSManagedObject subclass by an attribute value (date)
Solution 1
This is partly an issue with the Swift compiler not giving you a helpful error. The real issue is that NSDate
can't be compared with <
directly. Instead, you can use NSDate
's compare
method, like so:
days.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })
Alternatively, you could extend NSDate
to implement the Comparable
protocol so that it can be compared with <
(and <=
, >
, >=
, ==
):
public func <(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == NSComparisonResult.OrderedAscending
}
public func ==(a: NSDate, b: NSDate) -> Bool {
return a.compare(b) == NSComparisonResult.OrderedSame
}
extension NSDate: Comparable { }
Note: You only need to implement <
and ==
and shown above, then rest of the operators <=
, >
, etc. will be provided by the standard library.
With that in place, your original sort function should work just fine:
days.sort({ $0.date < $1.date })
Solution 2
In Swift 3, dates are now directly comparable:
let aDate = Date()
let bDate = Date()
if aDate < bDate {
print("ok")
}
Old swift: An alternative would be to sort on the timeIntervalSince1970 property of the date object, which is directly comparable.
days.sort({$0.date.timeIntervalSince1970 < $1.date.timeIntervalSince1970})
Solution 3
In swift2.1
use this lines of code
array.sortInPlace({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })
Solution 4
Update__ Swift 4,
let sortedData = dataToSort.sorted(by: { (obj1, obj2) -> Bool in
return obj1.date < obj2. date
})
Related videos on Youtube
Steven Hovater
Updated on July 09, 2022Comments
-
Steven Hovater almost 2 years
I'm trying to sort an array as laid out in the accepted answer to this question, but am running into the problem which Isuru mentions in the comments on that answer. Namely, the code which should sort the array by the entity's "date" attribute brings the compiler complaint "could not find member 'date'"
Here is the NSManagedObject subclass describing the entity:
import Foundation import CoreData @objc(Entry) class Entry: NSManagedObject { @NSManaged var date: NSDate @NSManaged var reflections: AnyObject @NSManaged var contactComment: NSSet @NSManaged var person: NSSet override func awakeFromInsert() { let now:NSDate = NSDate() self.date = now; } }
And here is the code which tries to sort the array:
lazy var entries:[Entry] = { var days:[Entry] = self.managedObjectContext!.requestEntity("Entry")as [Entry] days.sort({$0.date < $1.date}) var today:Entry = days.last! println(today.date) return days }()
Note that in the latter part of that code, I am able to access and log the "date" property for one of the entries, and the Compiler doesn't have a problem with it.
Is my syntax for sorting correct? Is there another issue with this code I'm not seeing?
-
nsij22 almost 9 yearsThis works perfectly for smaller amounts of data but when you have large amounts it takes a while to load. Is there a more efficient method?
-
Mike S almost 9 years@nsij22 since we're talking
NSManagedObject
s here, then those objects are probably coming from a core data store. In that case, the most efficient thing to do is probably to sort the data via the core data fetch request. Take a look atNSFetchRequest.sortDescriptors
: developer.apple.com/library/mac/documentation/Cocoa/Reference/… -
Fred Faust over 8 yearsI only thought of it when I needed the same thing and saw the accepted answer's first sentence, which was quite later than when the accepted answer was posted.