i want to sort a vector
vector<myclass> object;
where as myclass contains many int data variables, how can i sort my vector on any specific data variable of myclass.
i want to sort a vector
vector<myclass> object;
where as myclass contains many int data variables, how can i sort my vector on any specific data variable of myclass.
std::sort(object.begin(), object.end(), pred());
where, pred()
is a function object defining the order on objects of myclass
. Alternatively, you can define myclass::operator<
.
The function object approach (v
is the member on which you want to sort):
struct pred
{
bool operator()(myclass const & a, myclass const & b) const
{
return a.v < b.v;
}
};
In C++0x, you can write
std::sort(object.begin(), object.end(),
[](myclass const & a, myclass const &b){return a.v < b.v;});
Overload less than operator, then sort. This is an example I found off the web...
class MyData
{
public:
int m_iData;
string m_strSomeOtherData;
bool operator<(const MyData &rhs) const { return m_iData < rhs.m_iData; }
};
std::sort(myvector.begin(), myvector.end());
Source: here
A pointer-to-member allows you to write a single comparator, which can work with any data member of your class:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
template <typename T, typename U>
struct CompareByMember {
// This is a pointer-to-member, it represents a member of class T
// The data member has type U
U T::*field;
CompareByMember(U T::*f) : field(f) {}
bool operator()(const T &lhs, const T &rhs) {
return lhs.*field < rhs.*field;
}
};
struct Test {
int a;
int b;
std::string c;
Test(int a, int b, std::string c) : a(a), b(b), c(c) {}
};
// for convenience, this just lets us print out a Test object
std::ostream &operator<<(std::ostream &o, const Test &t) {
return o << t.c;
}
int main() {
std::vector<Test> vec;
vec.push_back(Test(1, 10, "y"));
vec.push_back(Test(2, 9, "x"));
// sort on the string field
std::sort(vec.begin(), vec.end(),
CompareByMember<Test,std::string>(&Test::c));
std::cout << "sorted by string field, c: ";
std::cout << vec[0] << " " << vec[1] << "\n";
// sort on the first integer field
std::sort(vec.begin(), vec.end(),
CompareByMember<Test,int>(&Test::a));
std::cout << "sorted by integer field, a: ";
std::cout << vec[0] << " " << vec[1] << "\n";
// sort on the second integer field
std::sort(vec.begin(), vec.end(),
CompareByMember<Test,int>(&Test::b));
std::cout << "sorted by integer field, b: ";
std::cout << vec[0] << " " << vec[1] << "\n";
}
Output:
sorted by string field, c: x y
sorted by integer field, a: y x
sorted by integer field, b: x y
Like explained in other answers you need to provide a comparison function. If
you would like to keep the definition of that function close to the sort
call (e.g. if it only makes sense for this sort) you can define it right there
with boost::lambda
. Use boost::lambda::bind
to call the member function.
To e.g. sort by member variable or function data1
:
#include <algorithm>
#include <vector>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
using boost::lambda::bind;
using boost::lambda::_1;
using boost::lambda::_2;
std::vector<myclass> object(10000);
std::sort(object.begin(), object.end(),
bind(&myclass::data1, _1) < bind(&myclass::data1, _2));