web-dev-qa-db-fra.com

Trier les objets dans un tableau par date

J'ai un tableau contenant un objet appelé HistoryObject et il a des propriétés telles que "date", "nom", etc.

Je trie le tableau comme suit:

 let sortedArray = HistoryArray.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedDescending})

qui est censé trier la date du plus récent au plus ancien. Par exemple:

  • 30 juin 2016
  • 29 juin 2016

etc..

Mais lorsque mon tableau contient "2 juillet 2016", le tableau trié devient:

  • 30 juin 2016
  • 29 juin 2016
  • 2 juil. 2016

Où "2 juillet 2016" devrait être sur le dessus après le tri, maintenant c'est sur le bas? Comment puis-je résoudre ce problème?

38
Nata Mio

Utilisation de Swift 4 & Swift 3

let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

for dat in testArray {
    let date = dateFormatter.date(from: dat)
    if let date = date {
        convertedArray.append(date)
    }
}

var ready = convertedArray.sorted(by: { $0.compare($1) == .orderedDescending })

print(ready)

Utilisation de Swift 2

Par exemple, vous avez le tableau avec les dates et un autre tableau 1, où vous allez enregistrer les dates converties:

var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [NSDate] = []

Après cela, nous convertissons les dates:

var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

for dat in testArray {
    var date = dateFormatter.dateFromString(dat)
    convertedArray.append(date!)
}

Et le résultat:

var ready = convertedArray.sort({ $0.compare($1) == .OrderedDescending })

print(ready)
75
Altimir Antonov

Pour Swift

var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

for dat in testArray {
    var date = dateFormatter.date(from: dat)
    convertedArray.append(date!)
}

//Approach : 1
convertedArray.sort(){$0 < $1}    

//Approach : 2
convertedArray.sorted(by: {$0.timeIntervalSince1970 < $1.timeIntervalSince1970})

print(convertedArray)
13
Ramkrishna Sharma

Éviter la variable supplémentaire de convertArray

Utilisation de Swift 4 & Swift 3

let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

var ready = convertedArray.sorted(by: { dateFormatter.date(from:$0).compare(dateFormatter.date(from:$1)) == .orderedDescending })

print(ready)
6
Prasen-ftech

Vous avez un tableau historyArray qui contient un tableau de HistoryObject. Chaque HistoryObject contient une chaîne de date sous la forme "MM jj, aaaa"

Modifier:

(Vous voulez trier vos objets d’historique par date. C’est une mauvaise idée d’essayer de trier les objets avec date chaînes selon ces chaînes de date, car vous devez convertir les chaînes de date en Cocoa Date objets pour chaque comparaison, vous devez donc convertir les dates en objets date et heure encore et encore. Dans un repère que j'ai fait, le tri s'exécute plus lentement de 1200X que si vous convertissez par lots vos chaînes de date en Date objets avant le tri, comme indiqué ci-dessous.)

Afin de le faire efficacement, vous devez d’abord obtenir les valeurs Date pour tous les objets. Une solution consiste à ajouter un Date var paresseux à votre HistoryObject calculé à partir de la chaîne de date. Si vous ne voulez pas faire cela, vous pouvez:

  1. Mappez votre tableau d'objets d'historique sur un tableau d'objets Date à l'aide d'un DateFormatter.
  2. Utilisez la fonction Zip() pour combiner le tableau d'objets d'historique et le tableau d'objets de date en un tableau de n-uplets.
  3. Trier le tableau de tuples.
  4. Mappez le tableau de tuples sur un tableau d'objets d'historique.

Le code à faire qui pourrait ressembler à ceci:

Version 1

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM dd, yyyy"

//I don't know what your HistoryObject looks like, so I'll fake it.
struct HistoryObject: CustomStringConvertible {
    let dateString: String
    let value: Int

    var description: String {
        return "date: \(dateString), value: \(value)"
    }
}

//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]

//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
    let value = Int(arc4random_uniform(1000))
    return HistoryObject(dateString: $0, value: value)
}

print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }

//Create an array of the `Dates` for each HistoryObject
let historyDates: [Date] = historyArray.map { dateFormatter.date(from: $0.dateString)!
}

//Combine the array of `Dates` and the array of `HistoryObjects` into an array of tuples
let historyTuples = Zip(historyArray, historyDates)

//Sort the array of tuples and then map back to an array of type [HistoryObject]
let sortedHistoryObjects = historyTuples.sorted { $0.1 > $1.1}
    .map {$0.0}

print("\n-----> After sorting <-----")
sortedHistoryObjects.forEach { print($0) }

Si vous ajoutez un lazy var date à votre HistoryObject le code de tri est BEAUCOUP plus simple:

Version 2:

//I don't know what your HistoryObject looks like, so I'll fake it.
class HistoryObject: CustomStringConvertible {
    let dateString: String
    lazy var date: Date = { dateFormatter.date(from: self.dateString)! }()
    let value: Int

    var description: String {
        return "date: \(dateString), value: \(value)"
    }

    init(dateString: String, value: Int) {
        self.dateString = dateString
        self.value = value
    }
}

//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]

//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
    let value = Int(arc4random_uniform(1000))
    return HistoryObject(dateString: $0, value: value)
}

print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }

let sortedHistoryArray = historyArray.sorted { $0.date > $1.date }
print("\n-----> After sorting <-----")
sortedHistoryArray.forEach { print($0) }
2
Duncan C