I want to find the max length of specific attributes from a vector of Person objects.
Below is an example of a Person object:
Person::Person(string first_name, string last_name, int the_age){
first = first_name;
last = last_name;
age = the_age;
}
I have a vector that stores Person objects, and I must print all the people out in a table, like so:
First Name Last Name Age
---------- ------------ ----
John Cool-Johnson 15
Paul Bob 1000
2 people
I need to find the max length of each attribute of a Person in order to grow each column according to the maximum length of name or age. How can I do this?
So far, I have tried lambdas using this code:
unsigned int max_name = *max_element(generate(people.begin(),people.end(), [](Person a){return a.getFirstName()})).size();
But I am not sure if this even works at all.
I must use <iomanip>, but I have no clue how it works.
Is there a better way?
CodePudding user response:
Your use of std::max_element() is wrong. It takes 2 iterators for input, which you are not providing to it. It would need to look more like this:
auto max_name = max_element(
people.begin(), people.end(),
[](const Person &a, const Person &b){
return a.getFirstName().size() < b.getFirstName().size();
}
)->getFirstName().size();
Alternatively:
vector<string> names;
names.reserve(people.size());
for(const Person &p : people) {
names.push_back(p.getFirstName());
}
auto max_name = max_element(
names.begin(), names.end(),
[](const string &a, const string &b){
return a.size() < b.size();
}
)->size();
However, since you will probably also want to do the same thing for the Last Name and Age columns, I would suggest simply looping though the people vector manually, keeping track of the max lengths as you go along, eg:
string::size_type max_fname = 10;
string::size_type max_lname = 9;
string::size_type max_age = 3;
for(const Person &p : people)
{
max_fname = max(max_fname, p.getFirstName().size());
max_lname = max(max_lname, p.getLastName().size());
max_age = max(max_age, to_string(p.getAge()).size());
}
Then you can output everything in a table, eg:
cout << left << setfill(' ');
cout << setw(max_fname) << "First Name" << " " << setw(max_lname) << "Last Name" << " " << setw(max_age) << "Age" << "\n";
cout << setfill('-');
cout << setw(max_fname) << "" << " " << setw(max_lname) << "" << " " << setw(max_age) << "" << "\n";
cout << setfill(' ');
for(const Person &p : people)
{
cout << setw(max_fname) << p.getFirstName() << " " << setw(max_lname) << p.getLastName() << " " << setw(max_age) << p.getAge() << "\n";
}
cout << people.size() << " people\n";
