我有以下代码,它们按 Info 类的多个字段对 Info
实例列表进行排序。 Java8 中的 lambda 表达式使事情变得简单明了。因此,我想知道在 C++ 中是否有类似的方法?如果不是,什么是最接近(或最优雅的)方法来处理这种多字段排序?谢谢!
public class Info {
Info(int wi, int bi, int di) {
w = wi;
b = bi;
d = di;
}
int w = -1;
int b = -1;
int d = -1;
}
List<Info> results = new ArrayList<Info>();
Collections.sort(results, (a,b) -> {
if (a.d == b.d) {
if(a.w == b.w) {
return a.b-b.b;
} else {
return a.w - b.w;
}
} else {
return a.d - b.d;
}
});
最佳答案
例如,您可以为类定义运算符 <。
这是一个演示程序
#include <iostream>
#include <tuple>
#include <list>
class Info
{
public:
Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
{
}
friend bool operator <( const Info &, const Info & );
friend std::ostream & operator << ( std::ostream &, const Info &info )
{
return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }";
}
private:
int w = -1;
int b = -1;
int d = -1;
};
bool operator <( const Info &a, const Info &b )
{
return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
}
int main()
{
std::list<Info> lst = { { 1, 2, 3 }, { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };
lst.sort();
for ( const auto &item : lst ) std::cout << item << '\n';
return 0;
}
它的输出是
{ 2, 1, 1 }
{ 2, 1, 3 }
{ 2, 2, 1 }
{ 3, 1, 2 }
{ 3, 2, 2 }
也就是说,您可以使用标准函数 std::tie
来完成所有工作。
或者使用容器 std::vector
#include <iostream>
#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>
class Info
{
public:
Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
{
}
friend bool operator <( const Info &, const Info & );
friend std::ostream & operator << ( std::ostream &, const Info &info )
{
return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }";
}
private:
int w = -1;
int b = -1;
int d = -1;
};
bool operator <( const Info &a, const Info &b )
{
return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
}
int main()
{
std::vector<Info> v = { { 1, 2, 3 }, { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };
std::sort( std::begin( v ), std::end( v ) );
for ( const auto &item : v ) std::cout << item << '\n';
return 0;
}
您可以使用 lambda 表达式,前提是您可以访问类的数据成员,例如通过成员函数。
#include <iostream>
#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>
class Info
{
public:
Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
{
}
int w = -1;
int b = -1;
int d = -1;
};
std::ostream & operator << ( std::ostream &, const Info &info )
{
return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }";
}
int main()
{
std::vector<Info> v = { { 1, 2, 3 }, { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };
std::sort( std::begin( v ), std::end( v ),
[]( const auto &a, const auto &b )
{
return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
} );
for ( const auto &item : v ) std::cout << item << '\n';
return 0;
}
关于C++中Java8 lambda类型的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57776075/