Ordenação de array de objetos em Swift: do simples ao complexo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como ordenar um array de objetos por propriedade em Swift: olhando sob o capô



Olá, colega! Se você já escreveu um aplicativo em Swift que exibe uma lista de usuários, produtos ou tarefas, certamente já se deparou com a necessidade de ordenar esses dados. A pergunta "How to sort an array of custom objects by property value?" é uma das mais populares no Stack Overflow. E não é à toa: à primeira vista parece simples, mas quando você se aprofunda, um mundo de possibilidades se abre.



Hoje não vamos apenas dar uma resposta pronta. Vamos analisar como a ordenação funciona sob o capô do Swift, quais mecanismos estão envolvidos e como escrever um código não apenas funcional, mas eficiente e elegante. Vamos nessa!



O que é ordenação de array de objetos em Swift?



Imagine: você tem um array de objetos User. Cada usuário tem nome, idade e avaliação. Você precisa exibi-los na tela, ordenados por idade (do mais novo para o mais velho).



Em Swift, isso é feito através dos métodos nativos sort() (ordena o array no local) e sorted() (retorna um novo array ordenado). Ambos aceitam uma closure que define a ordem.



struct User {    let name: String    let age: Int    let rating: Double}

let users = [ User(name: "Ana", age: 25, rating: 4.5), User(name: "Bruno", age: 30, rating: 3.8), User(name: "Carla", age: 22, rating: 4.9)]

// Ordenação por idade (crescente)let sortedByAge = users.sorted { $0.age < $1.age }print(sortedByAge.map { $0.name }) // ["Carla", "Ana", "Bruno"]


Pronto. Mas vamos entender o que realmente está acontecendo aqui.



Como o sort() funciona sob o capô: algoritmos e closures



O método sort() em Swift usa o algoritmo híbrido TimSort (nomeado em homenagem a Tim Peters). É um algoritmo de ordenação adaptativo e estável que combina merge sort e insertion sort. Ele é especialmente eficiente em dados parcialmente ordenados — olá, feeds de notícias e listas de tarefas!



A closure que você passa é um predicado de ordenação: uma função que recebe dois elementos e retorna true se o primeiro deve vir antes do segundo. O Swift chama essa closure repetidamente, comparando pares de elementos.



Importante: se seus objetos estiverem em conformidade com o protocolo Comparable, você pode até mesmo dispensar a closure:



struct User: Comparable {    let name: String    let age: Int        static func < (lhs: User, rhs: User) -> Bool {        return lhs.age < rhs.age    }}

let sortedUsers = users.sorted() // agora simples


Mas e se você precisar ordenar por diferentes propriedades em tempo de execução? É aí que entram os key paths (KeyPath).



Ordenação com KeyPath: elegância e flexibilidade



A partir do Swift 4, temos o KeyPath. É uma forma segura de referenciar uma propriedade de um objeto. Combinando KeyPath com closures, podemos escrever uma função de ordenação universal:



extension Array {    mutating func sort<T: Comparable>(by keyPath: KeyPath<Element, T>, ascending: Bool = true) {        sort { ascending ?            $0[keyPath: keyPath] < $1[keyPath: keyPath] :            $0[keyPath: keyPath] > $1[keyPath: keyPath]        }    }        func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>, ascending: Bool = true) -> [Element] {        return sorted { ascending ?            $0[keyPath: keyPath] < $1[keyPath: keyPath] :            $0[keyPath: keyPath] > $1[keyPath: keyPath]        }    }}

// Uso:users.sort(by: \\.age) // por idade (crescente)let sortedByRating = users.sorted(by: \\.rating, ascending: false) // por avaliação (decrescente)


Que beleza, não? Type-safe

Blogs

Book Recommendations