0

I have created a vector of vectors and I would like to sort them based on parameters that I define. Here, the sort() function takes the variable dataset defined as vector<vector<int>> to be just a vector<int>. Could someone explain what is going wrong?

Moreover, even after the above said problem is sorted out, compare() function would work only for hard coded indices. How should I go about it, if I would like to sort it based on different indices. Is there a method that I can mention to do so?

#include <iostream>
#include <vector>
#include <algorithm>

//void check_function(std::vector <std::vector <int> > *dataset)
//{
//    std::cout<<(*dataset)[0].size()<<std::endl;
//}

bool compare(const std::vector <std::vector <int> > &a, const std::vector <std::vector <int> > &b)
{
    return a[1] < b[1];
}

/* This works, but this sorts based on the first parameter of the vector rather than what I mention.
bool compare(const std::vector <int> &a, const std::vector <int> &b)
{
    return a < b;
}
*/    
int main()
{
    std::vector <int> data;
    std::vector <int> data2;
    std::vector <std::vector <int> > dataset;

    data.push_back(5);
    data.push_back(10);
    dataset.push_back(data);

    data2.push_back(5);
    data2.push_back(20);
    dataset.push_back(data2);

//    check_function(&dataset);
    std::sort(dataset.begin(), dataset.end(), compare);
    std::cout<< dataset[0][0]<<std::endl;

    return 0;
}
max66
  • 65,235
  • 10
  • 71
  • 111
Harikrishnan
  • 61
  • 1
  • 5
  • The issue is with the compare, not std::sort. You would need to create a compare that compares two instances of std::vector . – rcgldr Jan 07 '17 at 21:24

1 Answers1

1

Sorting a container, you need a function that compare couples of element contained in the container.

So, sorting a std::vector<std::vector<int>>, you need a function that receive a couples of std::vector<int>.

But your compare() receive a couple of std::vector<std::vector<int>>.

That is wrong.

Off Topic: your compare() function (IMHO) is very dangerous because access to the second element of both vector without checking if they contain at least two elements.

I think you should, at least, use at() instead operator[]; just to perform a bound cecking and, in case, obtain a catchable exception; something like

bool compare(const std::vector <int> & a, const std::vector <int> & b)
{
    return a.at(1) < b.at(1);
}

--- EDIT ---

The OP ask

how do I sort it based on an index that is decided in runtime?

Decided how? And where?

Suppose that is decided outside compare() (in the function that call std::sort(), by example), you can use a lambda function.

An example

#include <iostream>
#include <vector>
#include <algorithm>

int main()
 {
   std::vector <std::vector <int> > dataset;

   dataset.emplace_back(std::initializer_list<int>{200, 1});
   dataset.emplace_back(std::initializer_list<int>{5, 56});

   auto val = 1U;

   std::sort(dataset.begin(), dataset.end(),
             [val](const std::vector <int> &a, const std::vector <int> &b)
              { return  a.at(val) < b.at(val); });

   std::cout << dataset[0][0] << ", " << dataset[0][1] << std::endl;

   return 0;
 }
max66
  • 65,235
  • 10
  • 71
  • 111
  • std::sort will pass references to two elements of dataset to the compare function, each of these elements will be a std::vector . – rcgldr Jan 07 '17 at 21:31
  • [Please check the code here](https://gist.github.com/lharikrishnan1993/fae76536a9a55487c2e6774ac73e955b). Thanks. That works, but, how do I sort it based on an index that is decided during runtime, rather than hard coding it as 1? – Harikrishnan Jan 07 '17 at 21:35
  • @rcgldr - exactly; in the original code, `compare()` receive a couple of `std::vector> const &`; that is wrong. – max66 Jan 07 '17 at 21:38
  • @Harikrishnan - answer improved; hope this helps. – max66 Jan 07 '17 at 21:53
  • Thanks a lot! Need to learn lambda expressions to understand the logic completely. – Harikrishnan Jan 07 '17 at 22:06
  • @Harikrishnan - yes: give a look at lambda functions; they are really usefull. – max66 Jan 07 '17 at 22:08