std::sort 具有多个属性的相等对象
std::sort equal objects with multiple properties
我正在尝试对对象向量进行排序,使具有相同属性的对象彼此相邻。 Task
是一个 class,它接受并保存 3 个指向某处数据的指针。
vec.push_back(Task(&propertyOne, &propertyTwo, &propertyThree));
如果我有一个充满这些的向量,我想对它们进行排序,以便放置任何 propertyOne
、propertyTwo
和 propertyThree
相等的 Task
在向量中彼此相邻。如果两个 Task
对象属性不相等,那么它们去哪里并不重要。尽管他们最好靠近他们最共同的 Task
个对象。
我该怎么做?我已经尝试了明显的 (return a.propertyOne == b.propertyOne
) 但它似乎根本不起作用,而且它只比较了第一个 属性.
让我们的任务有三个属性,简称a、b、c。要以正确的顺序对此类任务进行排序,您必须执行以下操作:
std::sort(v.begin(), v.end(), [](const Task& l, const Task& r) {
if (l.a == r.a) {
if (l.b == r.b) {
return l.c < r.c;
}
return l.b < r.b;
}
return l.a < r.a;
});
最佳解决方案是使用 tuple<property*, property*, property*>
not a Task
. This comes with comparison operators 定义,这样您就可以简单地执行:vec.push_back(make_tuple(&propertyOne, &propertyTwo, &propertyThree))
对 vec
中的每个条目进行排序,然后只需执行:
sort(vec.begin(), vec.end())
如果 Task
必须比 tuple<property*, property*, property*>
更详细,您应该为 Task
定义比较运算符:
bool Task::operator< (const Task& rhs) {
return make_tuple(a, b, c) < make_tuple(rhs.a, rhs.b, rhs.c);
}
bool Task::operator== (const Task& rhs) {
return a == rhs.a && b == rhs.b && c == rhs.c;
}
一旦定义了这两个,您就可以再次执行:
sort(vec.begin(), vec.end())
我会使用包含几个三元运算符的简单 lambda 来实现
std::sort(v.begin(), v.end(), [](const Task& l, const Task& r)
{
return (l.a == r.a) ?
((l.b == r.b) ? (l.c < r.c) : (l.b < r.b)) :
(l.a < r.a);
});
这显然假设属性 a
和 b
可以使用 ==
进行比较,并且所有三个属性都可以使用 <
.[=18= 进行比较]
或者,您可能希望提供来自 <functional>
(std::equal_to
、std::less
等)的泛函的适当特化,并改用它们。
我正在尝试对对象向量进行排序,使具有相同属性的对象彼此相邻。 Task
是一个 class,它接受并保存 3 个指向某处数据的指针。
vec.push_back(Task(&propertyOne, &propertyTwo, &propertyThree));
如果我有一个充满这些的向量,我想对它们进行排序,以便放置任何 propertyOne
、propertyTwo
和 propertyThree
相等的 Task
在向量中彼此相邻。如果两个 Task
对象属性不相等,那么它们去哪里并不重要。尽管他们最好靠近他们最共同的 Task
个对象。
我该怎么做?我已经尝试了明显的 (return a.propertyOne == b.propertyOne
) 但它似乎根本不起作用,而且它只比较了第一个 属性.
让我们的任务有三个属性,简称a、b、c。要以正确的顺序对此类任务进行排序,您必须执行以下操作:
std::sort(v.begin(), v.end(), [](const Task& l, const Task& r) {
if (l.a == r.a) {
if (l.b == r.b) {
return l.c < r.c;
}
return l.b < r.b;
}
return l.a < r.a;
});
最佳解决方案是使用 tuple<property*, property*, property*>
not a Task
. This comes with comparison operators 定义,这样您就可以简单地执行:vec.push_back(make_tuple(&propertyOne, &propertyTwo, &propertyThree))
对 vec
中的每个条目进行排序,然后只需执行:
sort(vec.begin(), vec.end())
如果 Task
必须比 tuple<property*, property*, property*>
更详细,您应该为 Task
定义比较运算符:
bool Task::operator< (const Task& rhs) {
return make_tuple(a, b, c) < make_tuple(rhs.a, rhs.b, rhs.c);
}
bool Task::operator== (const Task& rhs) {
return a == rhs.a && b == rhs.b && c == rhs.c;
}
一旦定义了这两个,您就可以再次执行:
sort(vec.begin(), vec.end())
我会使用包含几个三元运算符的简单 lambda 来实现
std::sort(v.begin(), v.end(), [](const Task& l, const Task& r)
{
return (l.a == r.a) ?
((l.b == r.b) ? (l.c < r.c) : (l.b < r.b)) :
(l.a < r.a);
});
这显然假设属性 a
和 b
可以使用 ==
进行比较,并且所有三个属性都可以使用 <
.[=18= 进行比较]
或者,您可能希望提供来自 <functional>
(std::equal_to
、std::less
等)的泛函的适当特化,并改用它们。