I'm assuming for sake of discussion you are working with a std::vector<std::vector<int> >
. The same discussion applies for a 2D vector of other types.
If you want to sort the individual int
s so they are ordered within the std::vector<std::vector<int> >
then it's not possible to do directly. There is no iterator that can be obtained directly from a std::vector<std::vector<int>>
which runs over all of the nested int
s.
One way might be to set up a temporary copy into a std::vector<int>
(i.e. create a flattened 1D vector), sort that, and then copy the elements back. For example;
std::vector<std:vector<int> > vec;
// populate vec somehow
std::vector<int> elements(0);
// create a single std::vector<int> from the vector<vector<int>> by
// appending the vector<int>s end to end
for (const auto &row : vec)
{
elements.insert(elements.end(), row.begin(), row.end());
}
std::sort(elements.begin(), elements.end()); // sort in ascending order
// now copy the sorted elements back
auto start = elements.begin();
for (auto &row : vec) // non-const here since we seek to change the vector<int>s within vec
{
auto end = start + row.size();
std::copy(start, end, row.begin());
start = end;
}
The shenanigans in the last loop with row.size()
and row.begin()
deals with the possibility that the vector<int>
within vec
are of different sizes, so will change
{{5,6,7}, {1,2}, {3,4,8}}
to be
{{1,2,3}, {4, 5}, {6,7,8}}
rather than to something else such as to
{{1,2}, {3,4,5}, {6, 7, 8}}; // vector<int>s resized
Things can be simplified a little if you assume all the inner vectors are of the same size.
Alternatively, you might try hand-rolling a struct
/class
type that has all the properties of a random access iterator (which is what std::sort()
requires). That structure (or its member functions/operators) will need to both track which std::vector<int>
(within the 2D vector) AND the particular int
within that vector that it refers to. That will be moderately tricky (e.g. if the custom iterator refers to the last element of a particular std::vector<int>
, incrementing it must give a result that references the first element of the next vector<int>
). A std::vector<std::vector<int> >
simply does not have any built in capability to give you such an iterator directly. I'll leave rolling such a custom iterator as an exercise.