Ordenar un `std::vector` de Objetos por un Atributo en C++
Ordenar colecciones de objetos es una tarea habitual en cualquier aplicación. La biblioteca estándar de C++ proporciona el algoritmo std::sort, que permite ordenar un std::vector utilizando cualquier criterio definido por el desarrollador.
Clase de ejemplo
Supongamos la siguiente clase:
class Animal {
private:
int id;
std::string nombre;
public:
Animal(int id, const std::string& nombre)
: id(id), nombre(nombre) {}
int getId() const { return id; }
const std::string& getNombre() const { return nombre; }
};Y un vector con varios objetos:
std::vector<Animal> animales = {
{3, "Perro"},
{1, "Gato"},
{2, "Loro"}
};Ordenar por ID
La forma más sencilla consiste en utilizar std::sort junto con una expresión lambda.
std::sort(
animales.begin(),
animales.end(),
[](const Animal& a, const Animal& b)
{
return a.getId() < b.getId();
}
);Resultado:
1 - Gato
2 - Loro
3 - PerroLa lambda recibe dos objetos y devuelve true cuando el primer elemento debe ubicarse antes que el segundo.
Ordenar por nombre
También es posible ordenar por cualquier otro atributo.
std::sort(
animales.begin(),
animales.end(),
[](const Animal& a, const Animal& b)
{
return a.getNombre() < b.getNombre();
}
);Resultado:
Gato
Loro
PerroOrden descendente
Para invertir el orden basta con cambiar el operador de comparación.
std::sort(
animales.begin(),
animales.end(),
[](const Animal& a, const Animal& b)
{
return a.getId() > b.getId();
}
);Resultado:
3 - Perro
2 - Loro
1 - GatoDefinir un orden natural con operator<
Si la clase tiene un criterio de orden principal, puede sobrecargarse operator<.
bool operator<(const Animal& otro) const
{
return id < otro.id;
}Luego el ordenamiento se simplifica:
std::sort(animales.begin(), animales.end());Conclusión
std::sort es la herramienta estándar para ordenar colecciones en C++. Combinado con expresiones lambda permite ordenar objetos por cualquier atributo de forma simple, eficiente y legible. Cuando la clase posee un orden natural, la sobrecarga de operator< ofrece una solución aún más elegante.