1

I have the following 2d array that I get/create from an external .txt file.

string accountsArr[5][7] = {
  "[email protected]", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
  "[email protected]", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
  "[email protected]", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
  "[email protected]", "Tom", "Smith", "tuna20", "2000", "U", "Teacher",
  "[email protected]", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice"
};

I need to sort this array based on the "last name" column (column index 2 for each row), so I basically end up with:

string accountsArr[5][7] = {
  "[email protected]", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice",
  "[email protected]", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
  "[email protected]", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
  "[email protected]", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
  "[email protected]", "Tom", "Smith", "tuna20", "2000", "U", "Teacher"
};

How would I do this, programmatically? Using std::sort isn't working. I keep getting use of undeclared identifier sort.

int n = sizeof(accountsArr[0]) / sizeof(accountsArr[0][0]);
std::sort(accountsArr, accountsArr + n);

UPDATE: I need/want to know how to do this on a primitive string array specifically (no vectors, structs, etc).

8
  • Did you try using std::sort? Do you know how to use it, in C++? Are there examples of std::sort in your C++ textbook that you can look at? Is there anything specific about sorting that you're unsure about? Commented Nov 12, 2020 at 0:04
  • 1
    Why not create a struct for each of these fields and then overload operator <? Commented Nov 12, 2020 at 0:04
  • @SamVarshavchik The problem is my textbook doesn't seem to go into 2D arrays. It shows a lot of examples for 1d arrays with only numbers, which is much simpler than the problem i'm currently trying to solve. Commented Nov 12, 2020 at 0:06
  • There's nothing fundamentally different about sorting a one dimension array, a two dimension array, or a 42 dimension array. The basic principles are all the same. Unfortunately, we don't write code for other people on stackoverflow.com. You need to show your attempt to sort your array, and explain what your specific issue is. Commented Nov 12, 2020 at 0:09
  • 1
    Did I ever claim you could find it? I said exactly the opposite: you are unlikely to find someone else who happen to have written the same exact sort. C++ is the most complicated general purpose programming language in use today. Trying to implement something in C++ by searching for someone else doing the same thing, and copying it without having to learn the underlying principles, is not going to work. You need to learn how sorting works, in C++, how std::sort works, and then figuring out how to make it work with your arrays. There is no instant gratification in C++. Commented Nov 12, 2020 at 0:55

2 Answers 2

1

Let me give you a better way to approach your problem, using std::sort

First, create a proper structure for your data. I'll simplify your entries a bit. We also already implement operator< for this, as we need it later.

struct Person
{
    string first_name;
    string last_name;
    string email;

    Person(const string& first_name, const string& last_name, const string& email) :
        first_name(first_name), last_name(last_name), email(email) {}

    bool operator<(const Person& other) const { return last_name < other.last_name; }
};

C++ is meant to be an object-oriented language, and if you have any sort of regularly structured data, it should be at least a structure. As we have no need to encapsulate, with there being no way to render an object invalid, we can keep it a structure, otherwise we'd go for a class.

Raw array are usually not a good way to store data. The only good reason for using one is when things have to be hyper-optimized for speed. Therefore, we now convert your raw array into a proper container:

vector<Person> persons;
persons.reserve(rows); // <-- reserve allows for the memory to be properly pre-allocated
for(size_t i=0; i<rows; i++)
{
    persons.push_back(Person(accountsArr[i][1], accountsArr[i][2], accountsArr[i][0]));
}

Now that we have a proper container over a structure that defines operator<, all we have left to do is to call std::sort:

std::sort(persons.begin(), persons.end());

Done.

We could furthermore think about creating a class Persons that handles all of this, having a method read_file(const string& file) which reads the data, puts it into a member vector and then sorts it.

In any case, for the future, if people tell you to use std::sort, it won't hurt to search for a tutorial on how it is used. It has some other functionality to offer. Go for a description of it, like as in https://en.cppreference.com/w/cpp/algorithm/sort, and make sure to read and understand everything in it.
In this case, you were able to write a naive bubblesort, but when you program, you want to do as little as possible yourself. The STL functions are most likely more effective (your sorting is in O(N²), but sorting can be done in O(NlogN)) and is tested over and over again (creating a bug happens so easily).

Also, the STL has a built in std::swap, since you defined one yourself in your custom bubble sort.

In any way, consider putting some future code of yours on CodeReview.

Edit: as you wrote something about "unidentified identifier sort" in your question, you need to include headers if you want functionality. In case of std::sort, the right inclue is #include <algorithm>.

Sign up to request clarification or add additional context in comments.

Comments

0

So I finally figured this out by doing a "bubble sort". Here's how I implemented it. Hopefully this can help someone else who's having trouble finding any examples of sorting with 2d arrays by a specific column:

int rows = 5;
int col = 7;
string accountsArr[rows][col] = {
  "[email protected]", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
  "[email protected]", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
  "[email protected]", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
  "[email protected]", "Tom", "Smith", "tuna20", "2000", "U", "Teacher",
  "[email protected]", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice"
};

//do a bubble sort
for(int maxElement = rows - 1; maxElement > 0; maxElement--){
  for(int i = 0; i < maxElement; i++){
    //if current row "last name" column is > the next row "last name" column, swap them
    if(theAccounts[i][2] > theAccounts[i + 1][2]){
      std::swap(theAccounts[i], theAccounts[i + 1]);
    }
  }
}

3 Comments

It technically works, but you use naive bubble sort that has O(N²) complexity. Not that problematic for a small set of data. But in any case, totally unnecessary. std::sort is a thing.
Would be nice if it was more clear in documentation or my textbook that the std::sort function requires so much extra work in order to get a sort to work. I'm specifically working with a primitive string array and needed to be able to sort that, as is.
What you call extra work is what you should have done in any case, even if you would not use std::sort. A key feature of good code is readability. Will you remember in a year that the third entry in a row is the last name? Especially when the array is not hard-coded but read in from a file? Also, do you always have exactly five rows? If it can be dynamic, do you really want the hassle with dynamic memory allocation (requiring you to delete it later)? When you write big algorithms and put specific algorithms in a function, do you really want arrays decayed to pointers as arguments?

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.