Reputation: 45
I'd like to sort m_correlationValues in descending order and get ids of the sorted list. I've got this error. I'll appreciate your help. no match for 'operator=' (operand types are 'std::vector<std::pair<int, float> >' and 'void') return idx_correlation.second; });
void MatrixCanvas::SortMatrix()
{
int naxes = (int) m_correlationData.size();
std::vector<std::pair<int,float>> idx_correlations;
std::vector<std::pair<int,float>> sorted;
std::vector<int> idxs(naxes);
for(int idx =0; idx<naxes;idx++){
idx_correlations[idx] = std::make_pair(idx, m_correlationValues[chosen_row_id][idx]);}
// Wrong
sorted = std::sort(idx_correlations.begin(),
idx_correlations.end(),
[](std::pair<int,float> &idx_correlation){
return idx_correlation.second; });
// this will contain the order:
for(int i =0; i<naxes;i++)
idxs[i] = sorted[i].first;
}
Upvotes: 0
Views: 675
Reputation: 6131
You have two problems:
sort does not return a copy of the sorted range. It modifies the range provided. If you want the original to be left alone, make a copy of it first and then sort it.
std::sort
's third argument is a comparator between two values, which has the meaning of "less than". That is, "does a come before b?" For keeping the line short, I replaced your pair<...>
type with auto
in the lambda, but it'll be deduced to "whatever type of thing" is being sorted.
Note, if you want decreasing, just change <
to >
in the lambda when it compares the two elements.
Possible fix:
auto sorted = idx_correlations; // full copy
std::sort(sorted.begin(),
sorted.end(),
[](auto const & left, auto const & right) {
return left.first < right.first; });
After that, sorted
will be a sorted vector and idx_correlations will be left unchanged. Of course, if you don't mind modifying your original collection, there's no need to make this copy (and you can take begin/end of idx_correlations.
Upvotes: 2
Reputation: 37697
The other answers covered proper use of std::sort
, I wish to show C++20 std::rannges::sort
which have projection functionality what is close to thing you've tried to do:
std::vector<std::pair<int, float>> idx_correlations;
.....
auto sorted = idx_correlations;
std::ranges::sort(sorted, std::greater{}, &std::pair<int, float>::second);
https://godbolt.org/z/4rzzqW9Gx
Upvotes: 1
Reputation: 453
So the main issue I can see in your code, is that you're expecting the std::sort
to return the sorted vector, and this is NOT how it works.
https://en.cppreference.com/w/cpp/algorithm/sort
The solution in your case is to get the sorted vector out of the original vector, ie. sorted = idx_correlations
then sort the new vector.
sorted = idx_correlations;
std::sort( sorted.begin(), sorted.end(), your_comparator... );
This will do the trick while also maintaining the original vector.
Update: another issue is that your comparator will have TWO arguments not one (two elements to compare for the sort).
Upvotes: 2