Reputation: 15718
What would be a C++ way to sort struct
s with different amount of integer members. (Notice they're always int
s)
Suppose I have a struct with 3 int
s in it and I want to sort them:
void Sort(int& x, int& y, int& z)
{
//do stuff
if(x > y >...etc) x = y z=tmp //etc etc
}
struct Foo
{
int a {1};
int b {3};
int c {2};
};
int main()
{
Foo foo;
Sort(foo.a, foo.b, foo.c);
}
I could also pass Foo
as an argument instead of 3 int
s of course: void Sort(Foo& foo)
But suppose I have another struct with different amount of integers:
struct Bar
{
int a{7};
int b{8};
};
I would have to create another function for sorting:
void Sort(int& y, int& x) {}...
or even just for the struct Bar
itself:
void Sort(Bar& bar) {};
Now, I've got many structs and all of them contain different amount of int
s as data members. What is an overall way to sort the integer struct members in decreasing order?
-edit
I'll edit the question because maybe my fundamental approach to this is wrong. In my original problem I have two structs:
struct PlayerPrince {
int highCard;
int middleCard;
};
struct PlayerPrincess {
int highCard;
int middleCard;
int lowCard;
};
The values of the data members will be assigned accordingly to user input order. It can only be assured that int highCard
will only be the highest card after the struct is sorted.
struct PlayerPrince
does not need to have a lowCard
and I would like to sort the members of each struct without defining multiple functions. If there is a better design approach to the problem (as stated in the comments) I'd be glad to know.
Upvotes: 0
Views: 358
Reputation: 84541
As mentioned by @WhozCraig in the comments, the key is not to declare individual integer values within your struct
like int a; int b; int c;
, but instead use a container such as std::array
(if you have a fixed number of int
in that type struct), or use std::vector
(and add as many int
values as you need to the vector)
std::sort
provided by the <algorithm>
header then makes sorting on int
trivial as the default-compare function can be used without having to specify any special function of your own. Approaching the problem in this manner allows you to sort any number of integers contained withing your std::array
or std::vector
member regardless of how many integers are contained by using the standard .begin()
and .end()
iterators provided by the container.
Using std::array
For example, if you want to sort a struct with a fixed 3-integer array, you can simply do:
#include <iostream>
#include <array>
#include <algorithm>
struct Foo { /* struct Foo with std::array<int, 3> instead of 3 int variables */
std::array<int, 3> ints;
};
int main (void) {
Foo foo; /* instance of foo */
foo.ints.at(0) = 1; /* add 3-int to array ints */
foo.ints.at(1) = 3;
foo.ints.at(2) = 2;
/* sort foo.ints using default compare */
std::sort (foo.ints.begin(), foo.ints.end());
for (auto& i : foo.ints) /* output sorted foo.ints */
std::cout << " " << i;
std::cout << '\n';
}
Using std::vector
To use any number of integers in your struct simply replace std::array
with std::vector
and use .push_back()
to add as many integers to your vector as you like. The case above becomes:
#include <iostream>
#include <vector>
#include <algorithm>
struct Foo { /* struct Foo with std::vector<int> instead of separate integers */
std::vector<int> ints;
};
int main (void) {
Foo foo; /* instance of foo */
foo.ints.push_back(1); /* add 3-int to vector ints */
foo.ints.push_back(3);
foo.ints.push_back(2);
/* sort foo.ints using default compare */
std::sort (foo.ints.begin(), foo.ints.end());
for (auto& i : foo.ints) /* output sorted foo.ints */
std::cout << " " << i;
std::cout << '\n';
}
(note: with std::vector
you can add 1-integer
or 100000-integers
and the only thing that changes is the number of times you call foo.ints.push_back(x);
)
Using std::greater<T>()
for Descending Sort
The <functional>
header provides several standard comparisons such as std::greater<T>()
, std::less<T>()
, std::less_equal<T>()
, etc.. To sort the array or vector is descending our you can use std::greater<int>()
as the compare function, e.g.
/* sort foo.ints using std::greater<T>() compare */
std::sort (foo.ints.begin(), foo.ints.end(), std::greater<int>());
Example Use/Output
In both cases using the default sort the output is the same:
$ ./bin/sortfooints
1 2 3
(using std::greater<int>()
would result in 3 2 1
)
Look things over and let me know if you have further questions.
Upvotes: 1