只对向量中的一个类成员进行排序,其他成员保持不变
Sort just one member of the classes in a vector, leaving the other members unchanged
有大量的答案可以对成员变量的结构向量进行排序。使用std::sort
和谓词函数,比较结构成员很容易。真的很容易。
但我有一个不同的问题。假设我有以下结构:
struct Test {
int a{};
int b{};
int toSort{};
};
以及该结构的向量,例如:
std::vector<Test> tv{ {1,1,9},{2,2,8},{3,3,7},{4,4,6},{5,5,5} };
我不想对向量元素进行排序,而只想对成员变量中的值进行排序。因此,预期输出应等于:
std::vector<Test> tvSorted{ {1,1,5},{2,2,6},{3,3,7},{4,4,8},{5,5,9} };
我希望解决方案在某种程度上是一个通用解决方案。然后我想出了一个(抱歉(预处理器宏解决方案。请参阅以下示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
struct Test {
int a{};
int b{};
int toSort{};
};
#define SortSpecial(vec,Struct,Member)
do {
std::vector<decltype(Struct::Member)> vt{};
std::transform(vec.begin(), vec.end(), std::back_inserter(vt), [](const Struct& s) {return s.Member; });
std::sort(vt.begin(), vt.end());
std::for_each(vec.begin(), vec.end(), [&vt, i = 0U](Struct & s) mutable {s.Member = vt[i++]; });
} while (false)
int main()
{
// Define a vector of struct Test
std::vector<Test> tv{ {1,1,9},{2,2,8},{3,3,7},{4,4,6},{5,5,5} };
for (const Test& t : tv) std::cout << t.a << " " << t.b << " " << t.toSort << "n";
// Call sort macro
SortSpecial(tv, Test, toSort);
std::cout << "nnSortedn";
for (const Test& t : tv) std::cout << t.a << " " << t.b << " " << t.toSort << "n";
}
由于宏不应该在C++中使用,所以我的问题在这里:
1. 算法库的解决方案是否可行?
2. 或者这可以通过模板实现吗?
将当前解决方案转换为模板解决方案相当简单。
template <typename T, typename ValueType>
void SpecialSort(std::vector<T>& vec, ValueType T::* mPtr) {
std::vector<ValueType> vt;
std::transform(vec.begin(), vec.end(), std::back_inserter(vt), [&](const T& s) {return s.*mPtr; });
std::sort(vt.begin(), vt.end());
std::for_each(vec.begin(), vec.end(), [&, i = 0U](T& s) mutable {s.*mPtr = vt[i++]; });
}
我们可以通过传入向量和指向成员的指针来调用它。
SpecialSort(tv, &Test::toSort);
像这样(如果需要,您只需要复制、重命名和编辑其余变量的"switchToShort"功能(:
#include <iostream>
#include <vector>
struct Test {
int a{};
int b{};
int toSort{};
};
void switchToShort(Test &a, Test &b) {
if (a.toSort > b.toSort) {
int temp = a.toSort;
a.toSort = b.toSort;
b.toSort = temp;
}
}
//void switchToA(Test& a, Test& b) { ... }
//void switchToB(Test& a, Test& b) { ... }
inline void sortMemeberValues(std::vector<Test>& data, void (*funct)(Test&, Test&)) {
for (int i = 0; i < data.size(); i++) {
for (int j = i + 1; j < data.size(); j++) {
(*funct)(data[i], data[j]);
}
}
}
int main() {
std::vector<Test> tv { { 1, 1, 9 }, { 2, 2, 8 }, { 3,3 ,7 }, { 4, 4, 6 }, { 5, 5, 5} };
sortMemeberValues(tv, switchToShort);
//sortMemeberValues(tv, switchToA);
//sortMemeberValues(tv, switchToB);
for (const Test& t : tv) std::cout << t.a << " " << t.b << " " << t.toSort << "n";
}
使用 range-v3(很快范围为 C++20(,您可以简单地执行以下操作:
auto r = tv | ranges::view::transform(&Test::toSort);
std::sort(r.begin(), r.end());
演示
相关文章:
- 类成员重新排序
- 如何在 c++11 中静态断言 std::array 类成员进行排序?
- 按类成员的顺序对包含类对象的C++向量进行排序
- 只对向量中的一个类成员进行排序,其他成员保持不变
- 合并 2 个排序的链表。必需的成员函数 bool Merge(List342 &list1):
- 对结构int成员进行排序
- C++排序向量<double>与在<Object>双成员变量上键控的向量
- 如何对类成员向量进行排序
- 如何对同一数组索引下的结构成员进行排序?
- 对多个数据成员进行排序
- 根据类成员对同一密钥的多映射元素进行排序
- 在对结构数组的一个成员进行排序后,移动其成员的其余部分
- std::具有自定义比较函数结果的排序函数错误:必须调用对非静态成员函数的引用
- 排序链表-移动节点还是交换数据成员
- 如何为涉及对象成员、间接寻址和强制转换的排序算法实现lambda函数
- 使用 #include 按<algorithm>字符串数据成员对类对象的向量进行排序
- 通过私人成员对自定义对象进行排序
- 如何根据其中一个成员的值对结构数组进行排序,从而在另一个成员的基础上断开联系
- 根据数据成员对对象数组进行排序或筛选
- C++列表::按成员排序的类