Как сортировать быстрый массив, содержащий экземпляры подкласса 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)