1

I am just beginning in C++, and I was wondering if there was a way to sort a 2D array by the second value in each array. I have not found any way to do in online, so I am asking here.

For example, you would start with:

int exampleArray[5][2] = {
    {4, 20},
    {1, 4},
    {7, 15},
    {8, 8},
    {8, 1}
};

and after sorting, the array would be

int exampleArray[5][2] = {
    {8, 1},
    {1, 4},
    {8, 8},
    {7, 15},
    {4, 20}
};

In Python, you could just sort it using exampleArray.sort(key = lambda element : element[1]), but I do not know how to do it using C++

6
  • Related: stackoverflow.com/questions/5897319/… stackoverflow.com/questions/16894700/… Commented Sep 3, 2021 at 0:36
  • Counter question: What have you tried? You might only be a little wrong and we can sort that out in no time. Commented Sep 3, 2021 at 0:46
  • @user4581301 I have no idea how to even approach this. Commented Sep 3, 2021 at 0:51
  • 1
    Fair enough. Arrays in C++ are second-class citizens in C++ and are a LOT harder to deal with than you're used to coming in from Python where an array is closer in spirit to C++'s std::vector (and still not a great match). Here's an answer that should help you get started. You'll have to tweak the rules used in the lambda expression that's being passed to std::qsort because it is currently sorting based on column 1 with column 2 breaking ties. Commented Sep 3, 2021 at 0:57
  • @CoderTang I have not found any way to do in online -- Think outside the box. Commented Sep 3, 2021 at 1:07

3 Answers 3

4

The short answer is: don't do that. C++ inherited it's built-in array from C, and it simply isn't really a very good fit for what you're trying to do.

Something that's reasonably similar and easy to implement would be to use std::vector instead of arrays.

std::vector<std::vector<int>> someVector {
    {4, 20},
    {1, 4},
    {7, 15},
    {8, 8},
    {8, 1}
};

Sorting this based on the second item in each row is pretty trivial:

    std::sort(someVector.begin(), someVector.end(), 
        [](auto const &a, auto const &b) { return a[1] < b[1]; });

We can then print out the result to verify that it's working as expected:

for (auto const &row : someVector)
    std::cout << row[0] << "\t" << row[1] << "\n";

As you'd expect, this produces:

8   1
1   4
8   8
7   15
4   20
Sign up to request clarification or add additional context in comments.

Comments

1

Using vector is much simpler, but assuming you can't use std::vector, here is an alternate way of "sorting", based on the answer given here:

#include <iostream>
#include <algorithm>

int main()
{
    int exampleArray[5][2] = {
        {4, 20},
        {1, 4},
        {7, 15},
        {8, 8},
        {8, 1}
    };

    // create the indexing (there are 5 2D entries)
    int index[] = {0,1,2,3,4};

    // sort the index based on the second value in the 2D array    
    std::sort(index, index + 5, [&](int n1, int n2) 
             { return exampleArray[n1][1] < exampleArray[n2][1]; });

    // output results
    for (int i = 0; i < 5; ++i)
       std::cout << exampleArray[index[i]][0] << " " << exampleArray[index[i]][1] << "\n";
}

Output:

8 1
1 4
8 8
7 15
4 20

Basically, you want to sort the index array based on the second value in the 2D array. That's what the lambda function is stating -- the index array is being "sorted", and not the original 2D array.

Once the sorting is finished, the index array is used to access the items in the 2D array in a sorted fashion.

From there, if you want the changes stored in the actual 2D array, you could rebuild the original array using the sorted index:

    // rebuild the original array using the sorted index
    int tempArray[5][2] = {};
    for (int i = 0; i < 5; ++i)
    {
        tempArray[i][0] = exampleArray[index[i]][0];
        tempArray[i][1] = exampleArray[index[i]][1];
    }
    
    // copy the new sorted array to the original array
    memcpy(exampleArray, tempArray, sizeof(exampleArray));

Comments

0

You can use a struct to keep your data:

struct Data
{
    int x,y;
};
vector<Data> a;

using std::sort , you can use a lambda function to acheive your goal

std::sort(a.begin(),a.end(),[](Data e1,Data e2){return e1.y<e2.y;});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.