Ordenar dados é uma das operações mais comuns em programação. Rust oferece métodos de ordenação eficientes diretamente nos slices e vetores, com suporte a critérios customizados e ordenação estável ou instável. Nesta receita, você vai dominar todas as formas de ordenar dados em Rust.
Dependências
Todos os métodos de ordenação fazem parte da biblioteca padrão:
[package]
name = "receita-ordenar"
version = "0.1.0"
edition = "2021"
Código Completo
fn main() {
// =============================================
// 1. sort() — ordenação simples (estável)
// =============================================
let mut numeros = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
numeros.sort();
println!("sort(): {:?}", numeros);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
// Ordenar strings (ordem lexicográfica/alfabética)
let mut frutas = vec!["banana", "abacaxi", "manga", "cereja", "damasco"];
frutas.sort();
println!("Frutas ordenadas: {:?}", frutas);
// ["abacaxi", "banana", "cereja", "damasco", "manga"]
// =============================================
// 2. sort_unstable() — mais rápido, sem garantia de estabilidade
// =============================================
let mut valores = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
valores.sort_unstable();
println!("sort_unstable(): {:?}", valores);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
// =============================================
// 3. reverse() — inverter a ordem
// =============================================
valores.reverse();
println!("reverse(): {:?}", valores);
// [9, 8, 7, 6, 5, 4, 3, 2, 1]
// =============================================
// 4. sort_by() — ordenação com comparador customizado
// =============================================
let mut numeros = vec![5, 2, 8, 1, 9, 3];
// Ordem decrescente
numeros.sort_by(|a, b| b.cmp(a));
println!("Decrescente: {:?}", numeros);
// [9, 8, 5, 3, 2, 1]
// Ordenar floats (f64 não implementa Ord, precisa de sort_by)
let mut decimais = vec![3.14, 1.41, 2.72, 0.58, 1.73];
decimais.sort_by(|a, b| a.partial_cmp(b).unwrap());
println!("Floats ordenados: {:?}", decimais);
// [0.58, 1.41, 1.73, 2.72, 3.14]
// Floats decrescente
decimais.sort_by(|a, b| b.partial_cmp(a).unwrap());
println!("Floats decresc.: {:?}", decimais);
// =============================================
// 5. sort_by_key() — ordenar por uma propriedade
// =============================================
let mut palavras = vec!["Rust", "é", "incrível", "e", "rápido"];
// Ordenar por tamanho da string
palavras.sort_by_key(|s| s.len());
println!("Por tamanho: {:?}", palavras);
// ["é", "e", "Rust", "rápido", "incrível"]
// Ordenar por tamanho decrescente
palavras.sort_by_key(|s| std::cmp::Reverse(s.len()));
println!("Tamanho decresc.: {:?}", palavras);
// ["incrível", "rápido", "Rust", "é", "e"]
// =============================================
// 6. Ordenar structs customizadas
// =============================================
#[derive(Debug, Clone)]
struct Aluno {
nome: String,
nota: f64,
idade: u32,
}
let mut alunos = vec![
Aluno { nome: "Ana".into(), nota: 9.5, idade: 22 },
Aluno { nome: "Carlos".into(), nota: 7.0, idade: 25 },
Aluno { nome: "Bia".into(), nota: 9.5, idade: 20 },
Aluno { nome: "Daniel".into(), nota: 8.0, idade: 23 },
Aluno { nome: "Eva".into(), nota: 7.0, idade: 21 },
];
// Ordenar por nota (decrescente)
alunos.sort_by(|a, b| b.nota.partial_cmp(&a.nota).unwrap());
println!("\nPor nota (maior primeiro):");
for a in &alunos {
println!(" {} — nota: {:.1}, idade: {}", a.nome, a.nota, a.idade);
}
// Ordenar por múltiplos critérios: nota (desc), depois nome (asc)
alunos.sort_by(|a, b| {
b.nota.partial_cmp(&a.nota)
.unwrap()
.then(a.nome.cmp(&b.nome))
});
println!("\nPor nota (desc) e nome (asc):");
for a in &alunos {
println!(" {} — nota: {:.1}", a.nome, a.nota);
}
// =============================================
// 7. Obter vetor ordenado sem modificar o original
// =============================================
let original = vec![3, 1, 4, 1, 5, 9, 2, 6];
let mut ordenado = original.clone();
ordenado.sort();
println!("\nOriginal: {:?}", original);
println!("Ordenado: {:?}", ordenado);
// =============================================
// 8. Verificar se já está ordenado
// =============================================
let crescente = vec![1, 2, 3, 4, 5];
let misturado = vec![3, 1, 2];
println!("\n[1,2,3,4,5] está ordenado? {}", crescente.is_sorted());
println!("[3,1,2] está ordenado? {}", misturado.is_sorted());
// =============================================
// 9. Posição com busca binária (vetor deve estar ordenado)
// =============================================
let dados = vec![2, 4, 6, 8, 10, 12, 14];
match dados.binary_search(&8) {
Ok(pos) => println!("\n8 encontrado na posição {}", pos),
Err(pos) => println!("\n8 não encontrado, seria inserido na posição {}", pos),
}
match dados.binary_search(&7) {
Ok(pos) => println!("7 encontrado na posição {}", pos),
Err(pos) => println!("7 não encontrado, seria inserido na posição {}", pos),
}
}
Saída do Programa
sort(): [1, 2, 3, 4, 5, 6, 7, 8, 9]
Frutas ordenadas: ["abacaxi", "banana", "cereja", "damasco", "manga"]
sort_unstable(): [1, 2, 3, 4, 5, 6, 7, 8, 9]
reverse(): [9, 8, 7, 6, 5, 4, 3, 2, 1]
Decrescente: [9, 8, 5, 3, 2, 1]
Floats ordenados: [0.58, 1.41, 1.73, 2.72, 3.14]
Floats decresc.: [3.14, 2.72, 1.73, 1.41, 0.58]
Por tamanho: ["é", "e", "Rust", "rápido", "incrível"]
Tamanho decresc.: ["incrível", "rápido", "Rust", "é", "e"]
Por nota (maior primeiro):
Ana — nota: 9.5, idade: 22
Bia — nota: 9.5, idade: 20
Daniel — nota: 8.0, idade: 23
Carlos — nota: 7.0, idade: 25
Eva — nota: 7.0, idade: 21
Por nota (desc) e nome (asc):
Ana — nota: 9.5
Bia — nota: 9.5
Daniel — nota: 8.0
Carlos — nota: 7.0
Eva — nota: 7.0
Original: [3, 1, 4, 1, 5, 9, 2, 6]
Ordenado: [1, 1, 2, 3, 4, 5, 6, 9]
[1,2,3,4,5] está ordenado? true
[3,1,2] está ordenado? false
8 encontrado na posição 3
7 não encontrado, seria inserido na posição 3
Quando Usar Cada Método
| Método | Estável | Uso |
|---|---|---|
sort() | Sim | Ordenação padrão (crescente) |
sort_unstable() | Nao | Mais rápido; use quando não importa a ordem de iguais |
sort_by() | Sim | Comparador customizado (decrescente, floats) |
sort_by_key() | Sim | Ordenar por uma propriedade extraída |
reverse() | — | Inverter a ordem atual |
Estável significa que elementos com o mesmo valor mantêm sua ordem relativa original. sort_unstable() é geralmente mais rápido e usa menos memória, sendo a melhor escolha quando a estabilidade não importa.
Veja Também
- Filtrar Vetor em Rust — combine filtragem com ordenação para processar dados
- Iterar Coleções em Rust — iteradores para transformar dados antes de ordenar
- Usar HashMap em Rust — ordene entradas de um HashMap coletando em Vec
- Structs, Enums e Pattern Matching — como definir os tipos customizados usados nos exemplos
- Rust Cheatsheet — referência rápida de Vec e métodos de ordenação
- Como ordenar slices em Go — comparação com a abordagem de ordenação em Go