2012-01-17 18 views
12

¿Cómo puedo filtrar un vector de clase, studentList por su país de usar algoritmo? Lo que significa que solo se muestran los detalles de los estudiantes del país "América".C++ Para filtrar un vector de clase usando el algoritmo

bool checkCountry (string x, string y) 
{ 
    return (x == y); 
} 
vector<Student> studentList; 
studentList.push_back(Student("Tom", 'M', "91213242", "America")); 
studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe")); 
+0

necesita la [idioma borrar-remove] (http://en.wikipedia.org/wiki/Erase-remove_idiom). –

+1

@Oli: solo si quería eliminar las entradas no americanas. Lo interpreté como que quiere preservar el vector, pero mostrar solo ciertos elementos. –

+0

Tengo que conservar las otras entradas para que borrar-borrar no funcione? – delphi316

Respuesta

7

creo que esto lo que busca:

struct country_filter 
{ 
    country_filter(const std::string& a_country): country(a_country) {} 
    void operator()(const Student& a_s) const 
    { 
     if (country == a_s.country) 
     { 
      std::cout << a_s.name << "\n"; 
     } 
    } 
    std::string country; 
}; 

// 
std::for_each(studentList.begin(), studentList.end(), country_filter("Ireland")); 

C++ 11:

std::string country = "America"; 
std::for_each(studentList.begin(), studentList.end(), [&country] (const Student& a_s) 
{ 
    if (a_s.country == country) 
    { 
     std::cout << a_s.name << "\n"; 
    } 
}); 
8

Puede utilizar filter_iterator de impulso. Here is an example con la colección subyacente como una matriz ordinaria.

A continuación se muestra un ejemplo de código no probado para que juegue; Tenía que hacer ciertas suposiciones sobre Student (operator<< válida para la salida, país expuesto a través de std::string country() const)

struct checkCountry 
{ 
    std::string country; 
    bool operator()(const Student& x) 
    { 
    return (x.country() == country); 
    } 
}; 

int main() 
{ 
    std::vector<Student> studentList; 
    studentList.push_back(Student("Tom", 'M', "91213242", "America")); 
    studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe")); 

    typedef boost::filter_iterator<checkCountry, std::vector<Student>::iterator> FilterIter; 
    checkCountry predicate; 
    predicate.country = "America"; 
    FilterIter filter_iter_first(predicate, studentList.begin(), studentList.end()); 
    FilterIter filter_iter_last(predicate, studentList.end(), studentList.end()); 

    std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<Student>(std::cout, " ")); 
} 
6

puede utilizar un objeto de una clase que implementa el operador (). Esto se llama un funtor :

struct checkCountry { 
    const string& compare; 
    checkCountry(const string& compare) : compare(compare) {} 
    bool operator()(const string& x) { return x == compare; } 
}; 

vector<Student> studentList; 
studentList.push_back(Student("Tom", 'M', "91213242", "America")); 
studentList.push_back(Student("Jessilyn", 'F', "98422333", "Europe")); 
howMany = std::count_if(studentList.begin(), studentList.end(), checkCountry("America")); 

Puede utilizar un funtor en cualquier algoritmo que requiere un predicado unario, por ejemplo, std::count_if, std::find_if, etc.

+1

¿Desde cuándo son los países de América y Europa? – aerkenemesis

13
using std::copy_if; 
using std::ostream_iterator; 
using std::cout; 

enum Region { 
    AMERICA, 
    EUROPE, 
    REST_OF_WORLD 
}; 

bool is_american(const Student& student) 
{ 
    return student.isFrom(AMERICA); 
} 

copy_if(students.begin(), students.end(), 
     ostream_iterator<Student>(cout, "\n"), 
     is_american); 

Usando una lambda en C++ 11, y permitiendo elegidos regiones:

void show_students_from_region(const Region& region) 
{ 
    copy_if(students.begin(), students.end(), 
      ostream_iterator<Student>(cout, "\n"), 
      [&](const Student& student) { return student.isFrom(region); }); 
} 
+0

¿Qué ocurre si mi menú debe permitir al usuario elegir qué país desea filtrar? – delphi316

+0

Hay un error en el código anterior: especificador de captura faltante lambda, debe tener el valor predeterminado ([=] o [&]) o mencionar explícitamente la región - [región] o [y región]. –

+0

@MichaelPliskin Gracias, corregido. –

Cuestiones relacionadas