Święta!
Oczywiście można napisać 3/4 mniej kodu, żeby osiągnąć to, co chcesz, ale ja chciałem, żeby ładnie się z tego korzystało, tj. .ById(Descending).ByAge().ByLastName().Sort();
.
#include <iostream>
#include "Student.h"
#include "StudentCollection.h"
int main(int argc, char *argv[])
{
StudentCollection sc;
sc.push_back(Student(1, "imie", "nazwisko", 10));
sc.push_back(Student(2, "imie", "nazwisko", 9));
sc.push_back(Student(2, "imie", "costam", 11));
sc.push_back(Student(2, "imie", "jakistam", 11));
sc.push_back(Student(2, "wqe", "rewqe", 55));
sc.push_back(Student(1, "costam", "innego", 9));
sc.ById(Descending).ByAge().ByLastName().Sort();
for(std::list<Student>::iterator it = sc.begin(); it != sc.end(); it++)
{
std::cout << it->Id << ": " << it->FirstName.c_str() << " " << it->LastName.c_str() <<
" (" << it->Age << ")\n";
}
return 0;
}
Student.h
#pragma once
#include <iostream>
struct Student
{
int Id;
std::string FirstName;
std::string LastName;
int Age;
Student(int id, std::string firstName, std::string lastName, int age) :
Id(id), FirstName(firstName), LastName(lastName), Age(age) { }
};
StudentCollection.h
#pragma once
#include <list>
#include <vector>
#include "Student.h"
enum Field
{
Id, FirstName, LastName, Age
};
enum Order
{
Ascending, Descending
};
struct Sorting
{
Field Field;
Order Order;
Sorting(::Field field, ::Order order) : Field(field), Order(order) { }
};
class StudentCollection : public std::list<Student>
{
private:
std::vector<Sorting> _sortings;
public:
StudentCollection(void);
~StudentCollection(void);
bool operator() (const Student& first, const Student& second) const;
StudentCollection& ById(Order order = Ascending);
StudentCollection& ByFirstName(Order order = Ascending);
StudentCollection& ByLastName(Order order = Ascending);
StudentCollection& ByAge(Order order = Ascending);
StudentCollection& Sort();
};
StudentCollection.cpp
#include "StudentCollection.h"
StudentCollection::StudentCollection(void)
{
}
StudentCollection::~StudentCollection(void)
{
}
StudentCollection& StudentCollection::ById(Order order)
{
_sortings.push_back(Sorting(Id, order));
return *this;
}
StudentCollection& StudentCollection::ByFirstName(Order order)
{
_sortings.push_back(Sorting(FirstName, order));
return *this;
}
StudentCollection& StudentCollection::ByLastName(Order order)
{
_sortings.push_back(Sorting(LastName, order));
return *this;
}
StudentCollection& StudentCollection::ByAge(Order order)
{
_sortings.push_back(Sorting(Age, order));
return *this;
}
StudentCollection& StudentCollection::Sort()
{
if(_sortings.size() > 0)
sort(*this);
_sortings.clear();
return *this;
}
bool StudentCollection::operator() (const Student& first, const Student& second) const
{
for(std::vector<Sorting>::const_iterator it = _sortings.begin(); it != _sortings.end(); it++)
{
switch(it->Field)
{
case Id:
if(first.Id == second.Id) continue;
return it->Order == Ascending ? first.Id < second.Id : first.Id > second.Id;
break;
case FirstName:
if(first.FirstName.compare(second.FirstName) == 0) continue;
return it->Order == Ascending ? first.FirstName.compare(second.FirstName) < 0 :
first.FirstName.compare(second.FirstName) > 0;
break;
case LastName:
if(first.LastName.compare(second.LastName) == 0) continue;
return it->Order == Ascending ? first.LastName.compare(second.LastName) < 0 :
first.LastName.compare(second.LastName) > 0;
break;
case Age:
if(first.Age == second.Age) continue;
return it->Order == Ascending ? first.Age < second.Age : first.Age > second.Age;
break;
}
}
}