Как сортировать быстрый массив, содержащий экземпляры подкласса NSManagedObject, по значению атрибута (date)

Я пытаюсь отсортировать массив, как изложенный в принятом ответе на этот вопрос, но я столкнулся с проблемой, которую Isuru упоминает в комментариях к этому вопросу ответ. А именно, код, который должен сортировать массив по атрибуту "дата" объекта, приносит жалобу компилятора "не удалось найти дату участника"

Вот подкласс NSManagedObject, описывающий объект:

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

И вот код, который пытается отсортировать массив:

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

Обратите внимание, что во второй части этого кода я могу получить доступ и зарегистрировать свойство "date" для одной из записей, а у компилятора нет проблем с ним.

Является ли мой синтаксис для правильной сортировки? Есть ли другая проблема с этим кодом, который я не вижу?

Ответ 1

Отчасти это связано с тем, что компилятор Swift не дает вам полезной ошибки. Реальная проблема заключается в том, что NSDate нельзя сравнивать с < напрямую. Вместо этого вы можете использовать метод NSDate compare, например:

days.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })

В качестве альтернативы вы можете расширить NSDate для реализации протокола Comparable, чтобы его можно было сравнить с <<=, >, >=, ==):

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

Примечание. Вам нужно только реализовать < и == и показано выше, тогда остальная часть операторов <=, > и т.д. будет предоставлена ​​стандартной библиотекой.

При этом ваша оригинальная функция сортировки должна работать нормально:

days.sort({ $0.date < $1.date })

Ответ 2

В Swift 3 даты теперь прямо сопоставимы:

let aDate = Date()
let bDate = Date()

if aDate < bDate {

    print("ok")
}

Старый быстрый: Альтернативой было бы отсортировать значение timeIntervalSince1970 объекта даты, которое напрямую сопоставимо.

days.sort({$0.date.timeIntervalSince1970 < $1.date.timeIntervalSince1970})

Ответ 3

В swift2.1 используйте эти строки кода

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

Ответ 4

У меня есть один словарь, ключи которого находятся в формате даты, поэтому я должен сортировать словарь по дате. я скопировал все ключи в nsarray, затем отсортировал этот массив, используя следующий код.

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)