Ordenar un `std::vector` de Objetos por un Atributo en C++

177 palabras 1 minuto 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 - Perro

La 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
Perro

Orden 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 - Gato

Definir 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.