Swift: trier le tableau d'objets par ordre alphabétique


138

J'ai ceci:

class Movies {
  Name:String
  Date:Int
}

et une gamme de [Films]. Comment trier le tableau par ordre alphabétique par nom? J'ai essayé:

movieArr = movieArr.sorted{ $0 < $1 }

et

movieArr = sorted(movieArr)

mais cela ne fonctionne pas car je n'accède pas à l'attribut name de Movies.

Réponses:


297

Dans la fermeture à laquelle vous passez sort, comparez les propriétés par lesquelles vous souhaitez trier. Comme ça:

movieArr.sorted { $0.name < $1.name }

ou ce qui suit dans les cas que vous souhaitez contourner:

movieArr.sorted { $0.name.lowercased() < $1.name.lowercased() }

Note de bas de page: En général, seuls les types commencent par une lettre majuscule; Je recommanderais d'utiliser nameet date, pas Nameet Date.


Exemple, dans une aire de jeux:

class Movie {
    let name: String
    var date: Int?

    init(_ name: String) {
        self.name = name
    }
}

var movieA = Movie("A")
var movieB = Movie("B")
var movieC = Movie("C")

let movies = [movieB, movieC, movieA]
let sortedMovies = movies.sorted { $0.name < $1.name }
sortedMovies

sortedMovies sera dans l'ordre [movieA, movieB, movieC]

Mise à jour Swift5

channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
            let channelName1 = channel1.name
            let channelName2 = channel2.name
            return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)

Merci, je ne fais que commencer avec Swift et je ne connaissais pas l'utilisation des fermetures.
— cdpalmer

1
utilisez movies.sort au lieu de movies.sorted @Mike S
— Oskariagon

1
Merci pour l'explication. Amélioration de mon montage, ça devrait aller, s'il vous plaît jeter un oeil :)
— Julian Król

8
Attention, cela ne fonctionnera pas lors du tri des chaînes qui peuvent ou non être en majuscules. La comparaison de .lowercaseStringrésoudra ce problème.
— Matthieu Riegler le

2
@EricAya Notez que c'est sortedà nouveau dans Swift 3: D.
— dvp.petrov

45

Avec Swift 3, vous pouvez choisir l'une des méthodes suivantes pour résoudre votre problème.


1. Utilisation sorted(by:​)avec une Movieclasse non conforme au Comparableprotocole

Si votre Movieclasse n'est pas conforme au Comparableprotocole, vous devez spécifier dans votre clôture la propriété sur laquelle vous souhaitez utiliser la sorted(by:​)méthode d'Array .

Movie déclaration de classe:

import Foundation

class Movie: CustomStringConvertible {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

}

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0.name < $1.name })
// let sortedMovies = movies.sorted { $0.name < $1.name } // also works

print(sortedMovies)

/*
prints: [Avatar, Piranha II: The Spawning, Titanic]
*/

2. Utilisation sorted(by:​)avec une Movieclasse conforme au Comparableprotocole

Cependant, en rendant votre Movieclasse conforme au Comparableprotocole, vous pouvez avoir un code beaucoup plus concis lorsque vous souhaitez utiliser la sorted(by:​)méthode d'Array .

Movie déclaration de classe:

import Foundation

class Movie: CustomStringConvertible, Comparable {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

    static func ==(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name == rhs.name
    }

    static func <(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name < rhs.name
    }

}

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0 < $1 })
// let sortedMovies = movies.sorted { $0 < $1 } // also works
// let sortedMovies = movies.sorted(by: <) // also works

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

3. Utilisation sorted()avec une Movieclasse conforme au Comparableprotocole

En rendant votre Movieclasse conforme au Comparableprotocole, vous pouvez utiliser la sorted()méthode d'Array comme alternative à sorted(by:​).

Movie déclaration de classe:

import Foundation

class Movie: CustomStringConvertible, Comparable {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

    static func ==(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name == rhs.name
    }

    static func <(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name < rhs.name
    }

}

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted()

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

Hé, y a-t-il des différences. entre le 2 et le 3 (sauf movies.sorted(by: <)et movies.sorted())?
— Kamaldeep singh Bhatia

sorted(by:)et sorted()sont deux méthodes différentes. Vous pouvez utiliser array.sorted()comme alternative pour array.sorted(by: <).
— Imanou Petit

Oui, juste demander en cas de définition de classe, devons-nous changer quelque chose? Je veux dire, pouvons-nous avoir la même définition de classe pour les deux sorted(by:)et sorted()?
— Kamaldeep singh Bhatia

1
Oui, vous pouvez avoir la même implémentation de votre classe / structure qui, dans tous les cas, doit se conformer au Comparableprotocole.
— Imanou Petit

J'ai Array avec customObject lorsque je shoer dans l'ordre croissant, il ne court pas correctement. "1" "14""28""31""4""42""49"
— Krunal Nagvadia

16
let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })

l'ajout de .lowercased () a fonctionné pour moi après une longue période d'essais. Je ne comprends pas pourquoi, puisque tout le texte était en minuscules pour commencer.
— Tom Tallak Solbu

quand utiliser minuscules () changera tous les noms en minuscules pour être triés correctement :)
— m.alqadi

14

Pour ceux qui utilisent Swift 3, la méthode équivalente pour la réponse acceptée est:

movieArr.sorted { $0.Name < $1.Name }

1

Tableau trié Swift 4.2

arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })

0
*import Foundation
import CoreData


extension Messages {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Messages> {
        return NSFetchRequest<Messages>(entityName: "Messages")
    }

    @NSManaged public var text: String?
    @NSManaged public var date: Date?
    @NSManaged public var friends: Friends?

}

    //here arrMessage is the array you can sort this array as under bellow 

    var arrMessages = [Messages]()

    arrMessages.sort { (arrMessages1, arrMessages2) -> Bool in
               arrMessages1.date! > arrMessages2.date!
    }*
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.