[solucionado]Recorrer un map

Iniciado por josevc, 22 Mayo 2015, 19:31 PM

0 Miembros y 1 Visitante están viendo este tema.

josevc

Buenas,

class Persona{
public:
            ....
private:
         typedef map<Asignatura*, int>Asignaturas;
         Asignaturas asignaturas;
         ...
};


Un map como este lo podría recorrer de la siguiente forma:

void mostrarAsignaturas()
{
    for(Persona::Asignaturas::const_iterator i=asignaturas.begin(); i!=asignaturas.end(); i++)
           (i->first)->mostrar(); cout << i->second << endl;
}

*Teniendo la clase asignatura un método mostrar.


El problema es si complicamos esto un poco más y queremos imprimir el siguiente map:

typedef std::map<Empresa*, std::map<Persona*,Salario*> > AD;
AD empresa-empleado;


Quiero hacer lo mismo que antes, un metodo mostrar que dado una Empresa te devuelva todas las personas con sus respectivos salarios.  :rolleyes:

Pero no se como podría hacer algo así, no se como recorrer el map interno.

Espero que alguien pueda ayudarme,
Muchas gracias!



Peregring-lk

Respecto a tu primer recorrido, si utilizas C++11, lo más fácil es hacerlo de la siguiente forma:

Código (cpp) [Seleccionar]

void mostrarAsignaturas()
{
    for (const auto & i : asignaturas) { // Son dos sentencias. Necesitas las llaves!!!
       i.first->mostrar();
       cout << i.second << endl;
   }
}


Respecto al recorrido del map interno:

Código (cpp) [Seleccionar]

void mostrarAsignaturas(Empresa* e)
{
    for (const auto& i : empresa_empleado[e]) {
        i.first->mostrar();
        i.second->mostrar();
   }
}


A la vieja usanza (sin los `based-range for` ni `auto`s), sería:

Código (cpp) [Seleccionar]

void mostrarAsignaturas(Empresa* e)
{
    const AD& empleados_e = empresa_empleado[e];

    for (AD::const_iterator i = empleados_e.begin(); i != empleados_e.end(); ++i) {
        i->first->mostrar();
        i->second->mostrar();
   }
}


Otra variante (con `auto`s pero sin `based-range for`):

Código (cpp) [Seleccionar]

void mostrarAsignaturas(Empresa* e)
{
    const auto& empleados_e = empresa_empleado[e];

    for (auto i = empleados_e.begin(); i != empleados_e.end(); ++i) {
        i->first->mostrar();
        i->second->mostrar();
   }
}


Los `auto`s lo que hacen es deducir el tipo (aunque siempre deducen el valor por copia; si lo que quieres es una referencia, tienes que forzarla escribiendo `&` junto a `auto`; y si la referencia la quieres constante, pues pones también `const`).

Un `range-based for` como el siguiente (supongamos que `v` es un `vector<int>` no constante):

Código (cpp) [Seleccionar]

for (auto i : v) {
   /* codigo */
}


Sería equivalente a lo siguiente:

Código (cpp) [Seleccionar]

// `it` tiene tipo `vector<int>::iterator`
for (auto it = v.begin(); it != v.end(); ++it) {
   auto i = *it; // `i` tiene tipo `int`.
   /* codigo */
}


Y si fuera por referencia:


Código (cpp) [Seleccionar]

// `it` tiene tipo `vector<int>::iterator`
for (auto it = v.begin(); it != v.end(); ++it) {
   auto& i = *it; // `i` tiene tipo `int&`.
   /* codigo */
}


Espero que con todo ésto, te haya quedado claro como se recorren rangos :)