Suppose that we have a struct
and a std::vector
, defined as:
struct example {
int x;
int height;
std::string type;
};
std::vector<example> objects;
First of all, we sort objects
in ascending order, based on values of x
, which can be implemented pretty easy:
std::sort(objects.begin(), objects.end(), [](const example &a, const example &b) {
return a.x < b.x;
});
But if values of x
are the same, There are three conditions need to be handled based on other properties. Consider the following as our objects:
x:0,height:3,type:"start"
x:7,height:11,type:"start"
x:5,height:8,type:"end"
x:1,height:4,type:"start"
x:3,height:6,type:"start"
x:4,height:7,type:"start"
x:1,height:5,type:"start"
x:5,height:9,type:"end"
x:7,height:12,type:"end"
x:6,height:10,type:"start"
After insertion, I sort them based on values of x
using the code written above, and the result would look like this:
x:0,height:3,type:"start"
x:1,height:4,type:"start"
x:1,height:5,type:"start"
x:3,height:6,type:"start"
x:4,height:7,type:"start"
x:5,height:8,type:"end"
x:5,height:9,type:"end"
x:6,height:10,type:"start"
x:7,height:11,type:"end"
x:7,height:12,type:"start"
Now there are modifications I need to do to the above vector (which is sorted based on values of x
, only.
Condition 1 : If values of x
and type
are the same, and the type
equals to start , the object with the larger height
must come before.
Condition 2 : If values of x
and type
are the same, and the type
equals to end , the object with the smaller height
must come before.
Condition 3 : If values of x
are the same and the values of type
are not, the object with start type
must come before.
So, the final sorted vector should look like this:
x:0,height:3,type:"start"
x:1,height:5,type:"start"
x:1,height:4,type:"start"
x:3,height:6,type:"start"
x:4,height:7,type:"start"
x:5,height:8,type:"end"
x:5,height:9,type:"end"
x:6,height:10,type:"start"
x:7,height:12,type:"start"
x:7,height:11,type:"end"
How these conditions can be implemented?
Instead of writing just return ax < bx;
, insert all your conditions. What is important to notice is that the expression ax < bx
evaluates to a boolean
value: true or false. If the expression is true, the first element(in this case a), will come first in the sorted array.
You could create your conditions as such:
if(a.x == b.x) {
if(a.type.compare(b.type) == 0){ //the types are equal
//condition one
if(a.type.compare("start") == 0) {
return a.height > b.height;
}
//condition two
if(a.type.compare("end") == 0) {
return a.height < b.height;
}
}
else { //types are not equal, condition three
if(a.type.compare("start") == 0) //the type of a is start
return true;
else
return false;
}
}
else {
return a.x < b.x;
}
It would be a good idea to put this code in a compare function:
bool compare(const exampleStruct& a, const exampleStruct& b)
{
//the code written above
}
And call the std::sort as:
std::sort(objectVector.begin(), objectVector.end(), compare);
It's pretty straight forward. Just follow the logic in your comparator:
std::sort(objectVector.begin(), objectVector.end(), [](exampleStruct a, exampleStruct b) {
if (a.x != b.x)
return a.x < b.x;
// a.x == b.x
if (a.type == b.type)
{
if (a.type == "start")
return a.height > b.height;
if (a.type == "end")
return a.height < b.height;
throw std::invalid_argument("invalid type");
}
// a.x == b.x && a.type != b.type
if (a.type == "start")
return true;
if (b.type == "start")
return false;
throw std::invalid_argument("invalid type");
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.