Swift comment trier un tableau d'objets personnalisés par valeur de propriété

disons que nous avons une classe personnalisée nommée imageFile et cette classe contient deux propriétés.

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

beaucoup d'entre eux stockés dans la gamme

var images : Array = []

var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)

aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)

la question Est: Comment puis-je trier le tableau d'images par 'fileID' ASC ou DESC?

361
demandé sur mohacs 2014-06-10 02:27:01

15 réponses

tout d'abord, déclarez votre tableau comme un tableau dactylographié de sorte que vous puissiez appeler des méthodes lorsque vous itérez:

var images : [imageFile] = []

alors vous pouvez simplement faire:

Swift 2

images.sorted({ "151910920".fileID > .fileID })

Swift 3 & 4

images.sorted(by: { "151920920".fileID > .fileID })

l'exemple ci-dessus donne desc ordre de tri

671
répondu Alex Wayne 2018-02-12 13:18:19

[ mise à Jour pour Swift 3 à trier(en:) ] Ce, en exploitant une fuite de fermeture:

images.sorted { "151900920".fileID < .fileID }

où vous utilisez < ou > selon ASC ou DESC, respectivement. si vous voulez modifier le images tableau , puis utiliser le suivant:

images.sort { "151910920".fileID < .fileID }

si vous allez le faire à plusieurs reprises et préférez définir une fonction, une façon est:

func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
  return this.fileID > that.fileID
}

et ensuite utiliser comme:

images.sort(by: sorterForFileIDASC)
181
répondu GoZoner 2016-09-24 13:53:11

presque tout le monde donne comment directement, laissez-moi montrer l'évolution:

vous pouvez utiliser les méthodes d'instance de Array:

// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })

// types of closure's parameters and return value can be inferred by Swift, so they are omitted along with the return arrow (->)
images.sortInPlace({ image1, image2 in return image1.fileID > image2.fileID })

// Single-expression closures can implicitly return the result of their single expression by omitting the "return" keyword
images.sortInPlace({ image1, image2 in image1.fileID > image2.fileID })

// closure's argument list along with "in" keyword can be omitted, "151900920", , , and so on are used to refer the closure's first, second, third arguments and so on
images.sortInPlace({ "151900920".fileID > .fileID })

// the simplification of the closure is the same
images = images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in image1.fileID > image2.fileID })
images = images.sort({ "151900920".fileID > .fileID })

pour une explication détaillée du principe de fonctionnement du tri, voir la fonction triée .

47
répondu fujianjin6471 2016-03-12 03:56:46

Swift 3

people = people.sorted(by: { "151900920".email > .email })
38
répondu quemeful 2016-09-28 19:57:05

Dans Swift 3.0

images.sort(by: { (first: imageFile, second: imageFile) -> Bool in
    first. fileID < second. fileID
})
23
répondu jaiswal Rajan 2017-01-07 16:39:04

deux variantes

1) commande du tableau d'origine avec sortInPlace

self.assignments.sortInPlace({ "151900920".order < .order })
self.printAssignments(assignments)

2) utilisant un tableau alternatif pour stocker le tableau commandé

var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ "151910920".order < .order })
self.printAssignments(assignmentsO)
17
répondu Bernauer 2016-12-29 09:15:43

vous pouvez aussi faire quelque chose comme

images = sorted(images) {"151900920".fileID > .fileID}

ainsi votre tableau d'images sera stocké comme trié

16
répondu Nicolas Grenié 2014-07-14 18:49:09

avec Swift 4, Array a deux méthodes appelées sorted() et sorted(by:) . La première méthode, sorted() , a la déclaration suivante:

Renvoie les éléments de la collection, triés.

func sorted() -> [Element]

la deuxième méthode, sorted(by:) , comporte la déclaration suivante:

renvoie le éléments de la collection, triée en utilisant le prédicat que la comparaison entre les éléments.

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

1. Trier par ordre croissant pour des objets comparables

si le type d'élément de votre collection est conforme au protocole Comparable , vous pourrez utiliser sorted() pour trier vos éléments dans un ordre croissant. Le code de terrain de jeu suivant montre comment utiliser sorted() :

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

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

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

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted()
print(sortedImages)

/*
 prints: [ImageFile with ID: 100, ImageFile with ID: 200, ImageFile with ID: 300]
 */

2. Trier par ordre décroissant pour des objets comparables

si le type d'élément de votre collection est conforme au protocole Comparable , vous devrez utiliser sorted(by:) pour trier vos éléments par ordre décroissant.

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

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

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

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0 > img1
})
//let sortedImages = images.sorted(by: >) // also works
//let sortedImages = images.sorted { "151930920" >  } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

3. Trier par ordre croissant ou décroissant pour les objets non comparables

si le type d'élément de votre collection N'est pas conforme au protocole Comparable , vous devrez utiliser sorted(by:) pour trier vos éléments par ordre ascendant ou descendant.

class ImageFile: CustomStringConvertible {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0.fileID < img1.fileID
})
//let sortedImages = images.sorted { "151940920".fileID < .fileID } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

notez que Swift fournit également deux méthodes appelées sort() et sort(by:) comme contreparties de sorted() et sorted(by:) si vous devez trier votre collection en place.

16
répondu Imanou Petit 2017-09-24 11:36:01

Swift 2 à 4

la réponse originale cherchait à trier un tableau d'objets personnalisés à l'aide d'une propriété. Ci-dessous, je vais vous montrer quelques façons pratiques de faire ce même comportement avec les structures de données swift!

petites choses hors du chemin, j'ai changé ImageFile si légèrement. Avec cela à l'esprit, je crée un tableau avec trois fichiers image. Notez que les métadonnées sont une valeur optionnelle, passant par nil comme un paramètre est attendu.

 struct ImageFile {
      var name: String
      var metadata: String?
      var size: Int
    }

    var images: [ImageFile] = [ImageFile(name: "HelloWorld", metadata: nil, size: 256), ImageFile(name: "Traveling Salesmen", metadata: "uh this is huge", size: 1024), ImageFile(name: "Slack", metadata: "what's in this stuff?", size: 2048) ]

ImageFile possède une propriété nommée size. Pour les exemples suivants, je vais vous montrer comment utiliser les opérations de tri avec des propriétés comme la taille.

de la plus petite à la plus grande taille (<)

    let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size < next.size
    }

de la plus grande à la plus petite ( > )

    let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size > next.size
    }

ensuite, nous allons trier en utilisant le nom de la propriété String. De la même manière, utilisez le tri pour comparer les chaînes. Mais notez que le bloc intérieur renvoie un résultat de comparaison. Ce résultat définira le tri.

A-Z (.ordonnance de suspension)

    let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedAscending
    }

Z-A.crédits ordonnés)

    let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedDescending
    }

suivant est ma façon préférée de trier, dans de nombreux cas, on aura des propriétés optionnelles. Maintenant, ne vous inquiétez pas, nous allons trier de la même manière que ci-dessus sauf que nous avons à gérer néant! En production;

j'ai utilisé ce code pour forcer toutes les instances dans mon tableau avec des valeurs de propriété nul à être dernier. Ensuite, commandez les métadonnées en utilisant les valeurs supposées non emballées.

    let metadataFirst = images.sorted { (initial, next) -> Bool in
      guard initial.metadata != nil else { return true }
      guard next.metadata != nil else { return true }
      return initial.metadata!.compare(next.metadata!) == .orderedAscending
    }

il est possible d'avoir un tri secondaire pour les optionnels. Par exemple, on pourrait afficher des images avec des métadonnées et classées par taille.

9
répondu jnblanchard 2018-02-05 17:32:24

Swift 4.0 et 4.1. Tout d'abord, j'ai créé un tableau mutable de type imageFile () comme indiqué ci-dessous

var arr = [imageFile]()

créer image d'objet mutable de type imageFile () et attribuer une valeur aux propriétés comme indiqué ci-dessous

   var image = imageFile()
   image.fileId = 14
   image.fileName = "A"

Maintenant, ajoutez cet objet à array arr

    arr.append(image)

maintenant, assignez les différentes propriétés à un même objet mutable I. E image

   image = imageFile()
   image.fileId = 13
   image.fileName = "B"

maintenant, à nouveau ajouter l'objet image pour arraisonner 151990920"

    arr.append(image)

maintenant, nous allons appliquer ordre ascendant sur fileId propriété dans array arr objets. Utiliser < symbole pour l'ordre ascendant

 arr = arr.sorted(by: {"151950920".fileId < .fileId}) // arr has all objects in Ascending order
 print("sorted array is",arr[0].fileId)// sorted array is 13
 print("sorted array is",arr[1].fileId)//sorted array is 14

Maintenant, nous allons appliquer ordre Décroissant sur fileId propriété dans la gamme arr objets. Utilisez > le symbole pour L'ordre décroissant

 arr = arr.sorted(by: {"151960920".fileId > .fileId}) // arr has all objects in Descending order
 print("Unsorted array is",arr[0].fileId)// Unsorted array is 14
 print("Unsorted array is",arr[1].fileId)// Unsorted array is 13

Dans Swift 4.1. Pour les commandes triées utiliser

let sortedArr = arr.sorted { (id1, id2) -> Bool in
  return id1.fileId < id2.fileId // Use > for Descending order
}
8
répondu GSK 2018-09-18 06:21:09

si vous allez trier ce tableau à plus d'un endroit, il peut être logique de rendre votre type de tableau Comparable.

class MyImageType: Comparable, Printable {
    var fileID: Int

    // For Printable
    var description: String {
        get {
            return "ID: \(fileID)"
        }
    }

    init(fileID: Int) {
        self.fileID = fileID
    }
}

// For Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID < right.fileID
}

// For Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID == right.fileID
}

let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)

let a1 = [one, three, two]

// return a sorted array
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"

var a2 = [two, one, twoA, three]

// sort the array 'in place'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"
6
répondu kwerle 2015-04-17 18:48:53

si vous n'utilisez pas d'objets personnalisés, mais des types de valeurs qui implémentent un protocole Comparable (Int, String, etc..), vous pouvez simplement faire ceci:

myArray.sort(>) //sort descending order

un exemple:

struct MyStruct: Comparable {
    var name = "Untitled"
}

func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name < rhs.name
}
// Implementation of == required by Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()

value2.name = "A New Name"

var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)

anArray.sort(>) // This will sort the array in descending order
5
répondu dorian 2015-08-11 18:28:28

si vous voulez trier le tableau original des objets personnalisés. Voici une autre façon de le faire dans Swift 2.1

var myCustomerArray = [Customer]()
myCustomerArray.sortInPlace {(customer1:Customer, customer2:Customer) -> Bool in
    customer1.id < customer2.id
}

id est un entier. Vous pouvez également utiliser le même opérateur < pour les propriétés String .

Vous pouvez en apprendre plus sur son utilisation en regardant un exemple ici: Swift2: Clients Proches

2
répondu Hanny 2015-12-19 11:25:14
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

students.sort(by: >)

print(students)

Imprime : "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

1
répondu Siddharth Chauhan 2018-03-14 23:17:57

je fais comme ça et ça fonctionne:

var images = [imageFile]() images.sorted(by: {"151900920".fileID.compare(.fileID) == .orderedAscending })

0
répondu Illya Krit 2017-09-26 14:02:07