Smith Dwayne
Smith Dwayne

Reputation: 2797

Sort 2D vector by Multiple columns

I'm using the following boost algorithm to sort my 2D vector.

#include <vector>
#include <boost/algorithm/string.hpp>

using namespace std;


class StringListCompare
{
public:
  explicit StringListCompare(int column) : m_column(column) {}
  bool operator()(const vector<string>& lhs, const vector<string>& rhs)
  {
    // what do we do if lhs or rhs don't have (m_column + 1) elements?
    return lhs[m_column] < rhs[m_column];
  }
private:
  int m_column;
};

int main()
{
  std::vector <std::vector <std::string> > data;
  std::vector <std::string> temp;
  //
  // Load 2D vector 
  sort(data.begin(), data.end(), StringListCompare(2));

  //Print 2D vector after sorting by 2nd column
}

Here I can sort the vector by Only one column which i specified as argument. But I want to sort this vector by two columns. My first column should be in sorted. According the first column sort I want to sort the vector again by 2nd column. How can i do this ?

I want to sort first by the first column, and then sort the ones with equal first column to be sorted by the second column?

Upvotes: 0

Views: 1753

Answers (3)

distantTransformer
distantTransformer

Reputation: 119

If i got what you want, lexigraphical sort (and std::lexigraphical_compare predicate) would help.

Upvotes: 1

Smith Dwayne
Smith Dwayne

Reputation: 2797

I tried it for number. But I know this is type mismatch error.

class StringListCompare
{

public:
  explicit StringListCompare(int column, int column2, string fCol, string sCol) : m_column(column), m_column2(column2) , fColType(fCol), sColType(sCol) {}

  bool operator()(const vector<string>& lhs, const vector<string>& rhs)
  {

        if (lhs[m_column] == rhs[m_column])
        {
             if (fColType.compare("string")==0)
                return lhs[m_column2] < rhs[m_column2];
            else  if (fColType.compare("number")==0)
                return atoi(lhs[m_column2]) < atoi(rhs[m_column2]);
        }

        else
        {
             if (fColType.compare("string")==0)
                return lhs[m_column] < rhs[m_column];
            else  if (fColType.compare("number")==0)
                return atoi(lhs[m_column]) < atoi(rhs[m_column]);
        }

  }
private:
  int m_column;
  int m_column2;
  string fColType;
  string sColType;
};

Is there any logic available to do like this for different data type sorting?

Upvotes: 0

daramarak
daramarak

Reputation: 6145

What you want to is as @distantTransformer say a lexicographical_compare. It behaves almost like the StringListCompare that you have made, with the exception that it will go through the whole list of strings. You sort lists of strings not letters like the most common use case, but that doesn't matter for lexicographical_compare as it works with iterators.

If you as a learning experience rather want to do the comparison yourself, and expand your StringListCompare you can do it like this:

bool operator()(const vector<string>& lhs, const vector<string>& rhs)
{
   for (int i = 0; i < lhs.size(); ++i) {         
     if (rhs.size() <= i) return false; //rhs has fewer strings than lhs
     if (lhs[i] < rhs[i]) return true;
     if (lhs[i] > rhs[i]) return false;
     //for loop continues while the two vectors are equal
   }
   return true; //rhs must be equal or a have more strings than lhs
}

You could consider rewriting this using iterators, but this is a basic implementation.

Upvotes: 0

Related Questions