Galilean
Galilean

Reputation: 268

How to sort a 2d array in cpp by values of two columns?

I have a std::vector< std::vector<double> > array, the entries of which are

1 80 -0.15 -0.9 -0.15 0.6 0 -1.5 
1 81 -0.15 -0.9 -0.15 0.7 0 -1.6 
1 82 -0.15 -0.9 -0.15 0.8 0 -1.7 
1 83 -0.15 -0.9 -0.15 0.9 0 -1.8 
.
.
.
79 155 0.15 0.9 0.15 -0.9 0 1.8 
79 156 0.15 0.9 0.15 -0.8 0 1.7 
79 157 0.15 0.9 0.15 -0.7 0 1.6 
79 158 0.15 0.9 0.15 -0.6 0 1.5 

Each row has 8 elements. I want to sort the array by the 7th and 8th element using the std::sort function as

auto sortfunc = [](vector<double> va, vector<double> vb){ return (va[7] < vb[7] ) && (va[6]< vb[6] ); };

sort(array.begin(),array.end(), sortfunc );

The result is not a completely sorted array

3 153 -0.15 -0.7 0.1 -0.1 -0.25 -0.6 
2 154 -0.15 -0.8 0.1 0 -0.25 -0.8 
2 153 -0.15 -0.8 0.1 -0.1 -0.25 -0.7 
2 152 -0.15 -0.8 0.1 -0.2 -0.25 -0.6 
7 153 -0.1 -0.7 0.1 -0.1 -0.2 -0.6 
7 154 -0.1 -0.7 0.1 0 -0.2 -0.7 
.
.
.
74 94 0.1 0.8 -0.05 -0.5 0.15 1.3 
74 95 0.1 0.8 -0.05 -0.4 0.15 1.2 
74 96 0.1 0.8 -0.05 -0.3 0.15 1.1 
74 97 0.1 0.8 -0.05 -0.2 0.15 1 
77 100 0.15 0.7 -0.05 0.1 0.2 0.6 
77 99 0.15 0.7 -0.05 0 0.2 0.7 

This doesn't give me an array that is sorted by the given condition as the elements in 7th and 8th column doesn't appear in a particular order.

What am I doing wrong here?

Github Gist for the arrays is here

Upvotes: 1

Views: 212

Answers (2)

Alan Birtles
Alan Birtles

Reputation: 36379

sortfunc does not implement the requirements of Compare as it does not have a strict weak ordering. It therefore causes undefined behaviour when used with std::sort.

If you want to compare multiple values the easiest way is to use std::tuple which automatically compares the first value then only compares the second value if the first matches:

auto sortfunc = [](vector<double> va, vector<double> vb){ return std::tie(va[7], va[8]) < std::tie(vb[7], vb[8]); };

Upvotes: 2

Galik
Galik

Reputation: 48605

Your sort criteria looks off. I think you need something more like this:

auto sortfunc = [](std::vector<double> const& va, std::vector<double> const& vb)
{
    if(va[7] == vb[7])
        return va[6] < vb[6];

    return va[7] < vb[7];
};

Sort by the first column unless the first column is equal in which case sort according to the second column.

Upvotes: 3

Related Questions