I need to sort vector of structures by a given field.
To anyone who faces the same problem: I just made my own sort function and there you can pass in lambda as many variables as you want(not only two of them).
Here I used a lambda expression, but I can't define the field to sort by as lambda accepts only passed variables.
sort(patients.begin(), patients.end(), [](Patient a, Patient b) { return a.name > b.name; });
I can't do it just like this:
string sortfield = name;
sort(patients.begin(), patients.end(), [](Patient a, Patient b)
{
if(sortfield == "name") return a.name < b.name;
else if(sortfield == "age") return a.age < b.age;
...
});
- Because it will cause an error as lambda can use only passed variables, not local.
- It will be hard to expand. Each time when I will add new field to the structure, I will have to go back here and add one more "else if"
I also tried to use a pointer to a function-member, but it works the same way.
I could use switch-case like this:
enum Fields
{
Name, Gender, DateOfBirth
};
Fields field;
switch (field)
{
case Fields::Name:
sort(patients.begin(), patients.end(), [](Patient a, Patient b) { return a.name > b.name; });
break;
case Fields::Gender:
sort(patients.begin(), patients.end(), [](Patient a, Patient b) { return a.gender > b.gender; });
break;
case Fields::DateOfBirth:
sort(patients.begin(), patients.end(), [](Patient a, Patient b) { return a.dateOfBirth > b.dateOfBirth; });
break;
default:
break;
}
but then it will break OCP (Open Closed Principle). I will have to come back several times to add more "case" blocks when the structure will be expanded.
Is there a better way to do this?