J'essaie de trier un tableau comme indiqué dans la réponse acceptée à cette question , mais je rencontre le problème que Isuru mentionne dans les commentaires sur cette réponse. A savoir, le code qui doit trier le tableau par l'attribut "date" de l'entité apporte la plainte du compilateur "n'a pas pu trouver le membre 'date'"
Voici la sous-classe NSManagedObject décrivant l'entité:
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;
}
}
Et voici le code qui essaie de trier le tableau:
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
}()
Notez que dans la dernière partie de ce code, je suis en mesure d'accéder à la propriété "date" et de la journaliser pour l'une des entrées, et le compilateur n'a pas de problème avec elle.
Ma syntaxe de tri est-elle correcte? Y a-t-il un autre problème avec ce code que je ne vois pas?
C'est en partie un problème avec le compilateur Swift ne vous donnant pas une erreur utile. Le vrai problème est que NSDate
ne peut pas être comparé avec <
directement. Au lieu de cela, vous pouvez utiliser la méthode NSDate
de compare
, comme ceci:
days.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })
Vous pouvez également étendre NSDate
pour implémenter le protocole Comparable
afin qu'il puisse être comparé à <
(et <=
, >
, >=
, ==
):
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 { }
Remarque: Il vous suffit d'implémenter <
et ==
et illustré ci-dessus, puis reste des opérateurs <=
, >
, etc. seront fournis par la bibliothèque standard.
Avec cela en place, votre fonction de tri d'origine devrait très bien fonctionner:
days.sort({ $0.date < $1.date })
Dans Swift 3, les dates sont désormais directement comparables:
let aDate = Date()
let bDate = Date()
if aDate < bDate {
print("ok")
}
Old Swift: Une alternative serait de trier sur la propriété timeIntervalSince1970 de l'objet date, qui est directement comparable.
days.sort({$0.date.timeIntervalSince1970 < $1.date.timeIntervalSince1970})
Dans Swift2.1
utilise ces lignes de code
array.sortInPlace({ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending })
Update__ Swift 4,
let sortedData = dataToSort.sorted(by: { (obj1, obj2) -> Bool in
return obj1.date < obj2. date
})
J'ai un dictionnaire dont les clés sont au format date donc je dois trier le dictionnaire par date. j'ai copié toutes les clés dans nsarray puis trié ce tableau en utilisant le code suivant.
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)