There are several possible ways to do this. The easiest way is to wrap name , x and y in a struct:
struct Person { std::wstring name; int x; int y; };
Then you can have std::vector<Person> people and sort it (assuming C ++ 14)
std::sort(people.begin(), people.end(), [](auto const& lhs, auto const& rhs) { return lhs.name < rhs.name; });
However, if you know that this will cause performance problems due to fewer cache-related elements (i.e. you often repeat only x or only y ) and you are in a very limited environment such as high-performance games) I would suggest only sorting one vector. If you do not know what you are doing, you will need to compare both options.
Basically, there is a vector that tracks the order:
std::vector<std::wstring> name; std::vector<int> x; std::vector<int> y std::vector<std::size_t> ordering(name.size()); std::iota(ordering.begin(), ordering.end(), 0); std::sort(ordering.begin(), ordering.end(), [&](auto const& lhs, auto const& rhs) { return name[lhs] < name[rhs]; });
Then you can simply ordering over ordering to traverse each parallel vector in a new order.
It is possible that an additional level of indirection will make it less effective. For example, a CPU might think that there is a data dependency in which there is none. In addition, the extra data that we track in ordering could easily take up enough cache space to counteract the advantage of splitting name , x and y ; You need to know the specifications of your target architecture and profile.
If you want to continue iterating over them in this new order, you want to use this ordering vector to sort other vectors, since access to the elements will become random. This will counteract the benefits of storing vectors separately (unless the vectors are small enough to fit in the cache) anyway.
The easiest way to do this is to create a new vector:
std::vector<std::wstring> newNames; newNames.reserve(name.size()); for (auto i : ordering) { newNames.push_back(name[i]); }
Reconstructing vectors such as this you probably want to do if sorting occurs during initialization.