You can just use std::sort
to sort the vector, and define a custom comparator functor (i.e. class with overloaded operator()
).
You can store the indexes of sorting columns in a std::vector
(that will be part of the "state" of the custom comparator object), and compare strings from columns whose indexes are stored in that vector.
You start comparing values at column specified in the first index in the "sorting columns" vector; if they are the same, you continue comparing values at column specified in the next index in the vector, etc. This can be done inside a for
loop inside the body of comparator's operator()
overload.
See the following code as an example (compiled with g++ (GCC) 4.7.2):
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<vector<string>> BuildTestData()
{
vector<string> r1 = {"hello", "world", "1", "3", "4", "7", "2", "1"};
vector<string> r2 = {"world", "hello", "1", "4", "8", "4", "2", "1"};
vector<string> r3 = {"phone", "mouse", "2", "3", "5", "2", "1", "4"};
return vector<vector<string>>{r1, r2, r3};
}
void PrintData(const vector<vector<string>> & v)
{
for (size_t r = 0; r < v.size(); r++)
{
for (size_t c = 0; c < v[r].size(); c++)
cout << v[r][c] << ' ';
cout << '\n';
}
}
class StringListComparator
{
public:
explicit StringListComparator(vector<int> sortColumns)
: m_sortColumns( move(sortColumns) )
{
}
bool operator()(const vector<string>& lhs, const vector<string>& rhs) const
{
// For each sorting column:
for (size_t i = 0; i < m_sortColumns.size(); i++)
{
// Comparison with current column
const int currentColumn = m_sortColumns[i];
if (lhs[currentColumn] < rhs[currentColumn])
return true;
if (lhs[currentColumn] > rhs[currentColumn])
return false;
// lhs[currentColumn] == rhs[currentColumn],
// so check with next sorting column
}
return false;
}
private:
vector<int> m_sortColumns;
};
int main()
{
auto v = BuildTestData();
cout << "Before sorting:\n";
PrintData(v);
vector<int> sortColumns = {5, 7}; // indexes are 0-based
sort(v.begin(), v.end(), StringListComparator(sortColumns));
cout << "\nAfter sort:\n";
PrintData(v);
}
Sample run:
Before sorting:
hello world 1 3 4 7 2 1
world hello 1 4 8 4 2 1
phone mouse 2 3 5 2 1 4
After sort:
phone mouse 2 3 5 2 1 4
world hello 1 4 8 4 2 1
hello world 1 3 4 7 2 1