Steven Hovater
Steven Hovater

Reputation: 1419

How do I sort a swift array containing instances of NSManagedObject subclass by an attribute value (date)

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?

Upvotes: 45

Views: 31601

Answers (5)

Sagar Thukral
Sagar Thukral

Reputation: 70

Update__ Swift 4,

let sortedData = dataToSort.sorted(by: { (obj1, obj2) -> Bool in             
   return obj1.date < obj2. date
})

Upvotes: 2

Amol Pokale
Amol Pokale

Reputation: 183

I having one dictionary whose keys are in the date format so i have to sort the dictionary by date . i copied all the keys in nsarray then sort that array by using the following code.

let keys : NSArray = stackedBarDataDict.allKeys // stackedBarDataDict is Data Dictionary
    let dataArray = NSMutableArray()
    for index in 0...(stackedBarDataDict.allKeys.count - 1)
    {
        let dateone = keys.objectAtIndex(index)
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        let date1 = dateFormatter.dateFromString(dateone as! String)
        dataArray.addObject(date1!)
    }
    let array : NSArray = (dataArray as NSArray)
        let sortedArray = array.sortedArrayUsingComparator {
        (obj1, obj2) -> NSComparisonResult in

        let p1 = obj1 as! NSDate
        let p2 = obj2 as! NSDate
        let result = p1.compare(p2)
        return result
    }
    print(sortedArray)

Upvotes: 0

Fred Faust
Fred Faust

Reputation: 6800

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})

Upvotes: 16

Phani Sai
Phani Sai

Reputation: 1233

In swift2.1 use this lines of code

array.sortInPlace({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })

Upvotes: 10

Mike S
Mike S

Reputation: 42345

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 })

Upvotes: 124

Related Questions