Trier un Array

heliohelio Membre

Bonsoir à  tous,


Quelle est votre méthode pour trier par date de la plus récente à  la plus ancienne et avec le moins d'instructions possibles ce tableau :



["février 2017", "mars 2017", "mai 2017", "janvier 2017", "avril 2017"]

sachant que j'ai obtenu ce tableau avec cette instruction :



let allKeys = Set<String>(arrayOfNews.filter({!$0.section.isEmpty}).map{$0.section})

pour n'avoir qu'une fois les mois même si j'avais plusieurs news avec février 2017 par exemple.


 


Merci.


Réponses

  • Joanna CarterJoanna Carter Membre, Modérateur
    Le problème, c'est que tu n'as pas un tableau de dates, tu as un tableau de strings ; ce qui est difficile à  trier de cette forme.
  • LarmeLarme Membre
    juin 2017 modifié #3

    Créer un DateFormatter pour transformer ces String en Date.


    Utiliser sorted et comparer ces dates.


     


    Car sinon, comparer les String, ça n'a pas de sens, car "janvier" se trouve après "février" si on classe par ordre de "char" (alphabétiquement), et l'année n'est pas prise en compte.


    Donc, il faut bien passer par des dates, et en Swift, les dates peuvent aisément utiliser "<" pour être comparées (appel en douce sur son timeStamp qui doit être un TimeInterval et donc juste appliquer "<" sur un Double). Ce qui n'est pas le cas en Objective-C, il aurait fallut utiliser compare:


     


     


    Tester dans playground sans être développeur Swift (donc oust les règles wrapp, ? et !), c'est plus pour la logique qu'autre chose.



    let array:[String] = ["février 2017", "mars 2017", "mai 2017", "mai 2015",  "janvier 2017", "avril 2017"]
    let dateFormatter = DateFormatter.init()
    dateFormatter.dateFormat = "MMMM yyyy"
    dateFormatter.locale = Locale.init(identifier: "fr_FR")
    //Vérification debug que les dates sont correctement parsées avec le dateFormatter
    for (index, str) in array.enumerated()
    {
        print("str \(str)")
        let date = dateFormatter.date(from: str)
        print("date \(date)")
    }
    let sortedArray = array.sorted(by: {dateFormatter.date(from: $0)! < dateFormatter.date(from: $1)!})
    print("sortedArray \(sortedArray)") 

    Output:



    ​str février 2017
    date Optional(2017-01-31 23:00:00 +0000)
    str mars 2017
    date Optional(2017-02-28 23:00:00 +0000)
    str mai 2017
    date Optional(2017-04-30 22:00:00 +0000)
    str mai 2015
    date Optional(2015-04-30 22:00:00 +0000)
    str janvier 2017
    date Optional(2016-12-31 23:00:00 +0000)
    str avril 2017
    date Optional(2017-03-31 22:00:00 +0000)
    sortedArray ["mai 2015", "janvier 2017", "février 2017", "mars 2017", "avril 2017", "mai 2017"]

    En Objective-C pour faire zoli et parce que j'aime les crochets et les blocks de filter/sort

     



    NSArray *array = @[;@février 2017, @mars 2017, @mai 2017, @mai 2015@janvier 2017, @avril 2017];   
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@MMMM yyyy];
    [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@fr_FR]];   
    NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSString * _Nonnull obj1, NSString *  _Nonnull obj2) {
    return [[dateFormatter dateFromString:obj1] compare:[dateFormatter dateFromString:obj2]];
    }];
    NSLog(@sortedArray: %@", sortedArray);

  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2017 modifié #4

    Et, après que l'on a vérifié la conversion, on pourrait réduire le code en Swift à  :



    let array = ["février 2017", "mars 2017", "mai 2017", "mai 2015", "janvier 2017", "avril 2017"]

    let dateFormatter = DateFormatter()

    dateFormatter.dateFormat = "MMMM yyyy"

    dateFormatter.locale = Locale(identifier: "fr_FR")

    let sortedArray = array.map { dateFormatter.date(from: $0)! }.sorted {$0 < $1}

    print(sortedArray)

  • heliohelio Membre

    Merci pour les codes !


  • samirsamir Membre


     


    Et, après que l'on a vérifié la conversion, on pourrait réduire le code en Swift à  :



    let array = ["février 2017", "mars 2017", "mai 2017", "mai 2015", "janvier 2017", "avril 2017"]

    let dateFormatter = DateFormatter()

    dateFormatter.dateFormat = "MMMM yyyy"

    dateFormatter.locale = Locale(identifier: "fr_FR")

    let sortedArray = array.map { dateFormatter.date(from: $0)! }.sorted {$0 < $1}

    print(sortedArray)



     plutôt une flatMap pour éviter le force unwraping!



    let sortedArray = array.flatMap { dateFormatter.date(from: $0) }.sorted {$0 < $1}
  • Joanna CarterJoanna Carter Membre, Modérateur


     


     plutôt une flatMap pour éviter le force unwraping!



    let sortedArray = array.flatMap { dateFormatter.date(from: $0) }.sorted {$0 < $1}



     


    Yesss !  :p   :p

Connectez-vous ou Inscrivez-vous pour répondre.