1

I have already tried the below code but i want to use this same function for sorting based on different columns.

This given code is sorting based on first column only.

bool sortcol( const vector <int> v1, const vector <int> v2)
{
return v1[0]<v2[0];
}

sort(ArrOfTimings.begin(), ArrOfTimings.end(), sortcol);

Is there any way possible to not make multiple functions but making it all work with one only.

Something like this

bool sortcol(int ind, const vector <int> v1, const vector <int> v2)
{
return v1[ind]<v2[ind];
}

sort(ArrOfTimings.begin(), ArrOfTimings.end(), sortcol(0));
Mayank_pawar
  • 54
  • 10
  • What if those vectors contain thousands of elements? A better approach would be to sort an index array instead of swapping out entire vectors on each out-of-order item. – PaulMcKenzie Jun 01 '22 at 18:04
  • that way i might lose data. The data in each vector is related. – Mayank_pawar Jun 01 '22 at 18:14
  • You are not losing any data. The index tells you where the sorted items are. See my answer below. – PaulMcKenzie Jun 01 '22 at 18:16
  • Also [see this answer](https://stackoverflow.com/questions/46382252/sort-array-by-first-item-in-subarray-c/46382976#46382976). I will probably remove my answer, and have you take a look at this answer, as it explains everything to you. In that example, the sorting is done on column 0, but all you have to do is replace the `0` with `column`. Everything else basically stays the same. If you want an example: [see this](http://coliru.stacked-crooked.com/a/48ab6e65d451ccef). – PaulMcKenzie Jun 01 '22 at 18:22
  • okay now I get it. Its good when vector contains large number of items. I used this method too but it takes extra space thats why swapping vectors themselves. My vectors have only three elements anyways, so – Mayank_pawar Jun 01 '22 at 18:29
  • I provided the comments to the alternate solution in case others are doing a search for the same thing you are doing, but want to use an index array (or are not aware of it, and then see that it is a better solution). – PaulMcKenzie Jun 01 '22 at 18:29

1 Answers1

2

You cannot pass additional info to a free function used for comparison for std::sort by means other than global data.

You can create a struct with a member variable storing the column to compare in addition to providing a call operator for comparing the values though.

I'd prefer a lambda, since it results in shorter code though: Simply capture the index.

Note: It's also beneficial to avoid copying the vector by using references as parameters.

void SortByColumn(std::vector<std::vector<int>> & data, size_t column)
{
    std::sort(data.begin(), data.end(),
              [column](std::vector<int> const& v1, std::vector<int> const& v2)
              {
                  return v1[column] < v2[column];
              });
}
fabian
  • 80,457
  • 12
  • 86
  • 114
  • Can the lambda take an additional argument to use in the comparison? for instance, a string ("ASC" or "DSC") that will determine if the sorting is ascending or descending – Barbarossa Jul 12 '23 at 17:10
  • @Barbarossa You cannot add a function parameter, since `std::sort` passes 2 parameters to the functor. You can add more stuff to the capture though, see https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture. Personally I'd prefer doing the case distinction outside of the lambda though and using 2 separate calls to `std::sort` with 2 different lambdas based on the string... – fabian Jul 12 '23 at 17:21
  • Yes, I was referring to the lambda function. The link is perfect, thanks! I wasn't sure if it would go inside the captures, or the params. – Barbarossa Jul 12 '23 at 17:39