sorting the value not the key

G

Gary Wessle

Hi

which container I can use to do the following,

I have a data file looking like
name age
jack 32
sam 12
sue 44

I need to sort them by age so that it would be

sam 12
jack 32
sue 44

I don't think map will let me sort its values, do I need to something
like this?

class mytype
{
string name;
int age;
public:
mytype(string n, int a){}
}

mytype jack("jack",32);
mytype sam("sam",12);
mytype sue("sue",44);

vector<mytype> groupA;
groupA.push_back(jack);
....

****************
how do I sort groupA by age?
****************

thanks
 
M

mlimber

Gary said:
Hi

which container I can use to do the following,

I have a data file looking like
name age
jack 32
sam 12
sue 44

I need to sort them by age so that it would be

sam 12
jack 32
sue 44

I don't think map will let me sort its values, do I need to something
like this?

class mytype
{
string name;
int age;
public:
mytype(string n, int a){}
}

mytype jack("jack",32);
mytype sam("sam",12);
mytype sue("sue",44);

vector<mytype> groupA;
groupA.push_back(jack);
...

****************
how do I sort groupA by age?
****************

thanks

Define an operator< function for two mytype objects, then use
std::sort. See the last example here:

http://www.cppreference.com/cppalgorithm/sort.html

Cheers! --M
 
T

Thomas Tutone

Gary said:
Hi

which container I can use to do the following,

I have a data file looking like
name age
jack 32
sam 12
sue 44

I need to sort them by age so that it would be

sam 12
jack 32
sue 44

I don't think map will let me sort its values, do I need to something
like this?

class mytype
{
string name;
int age;
public:
mytype(string n, int a){}

add this here:

int getAge() const { return age; }
}

mytype jack("jack",32);
mytype sam("sam",12);
mytype sue("sue",44);

vector<mytype> groupA;
groupA.push_back(jack);
...

****************
how do I sort groupA by age?

#include <functional>

using namespace std;

typedef const mytype& crMytype;

struct less_age : public binary_function<crMytype, crMytype, bool> {
bool operator()(crMytype x, crMytype y)
{ return x.getAge() < y.getAge(); }
};

sort(groupA.begin(), groupA.end(), less_age());

Best regards,

Tom
 
D

Daniel T.

Gary Wessle <[email protected]> said:
Hi

which container I can use to do the following,

I have a data file looking like
name age
jack 32
sam 12
sue 44

I need to sort them by age so that it would be

sam 12
jack 32
sue 44

I don't think map will let me sort its values.

Then make the age the key... (You might want to use a multi-map for
this.)
 
E

Earl Purple

I like your solution best of the 3 but:

Thomas said:
add this here:

int getAge() const { return age; }
}

#include <functional>

using namespace std;

typedef const mytype& crMytype;

struct less_age : public binary_function<crMytype, crMytype, bool> {
bool operator()(crMytype x, crMytype y)
{ return x.getAge() < y.getAge(); }
};

of course you wouldn't put using namespace std; in a header. But you
might want this functor in a header. You might even nest it in the
class.

Now is there a binder for this? I don't know, let's try to create one:

template < typename T >
struct less_mem_fun_ref : public binary_function< const T & t1, const T
& t2, bool >
{
typedef bool (* T::pred )(void); // sorry I can't remember the
syntax
Pred pred;
less_mem_fun_ref( Pred p ) : pred( p ) {}

bool operator() ( const T& t1, const T& t2 )
{
return t1.pred() < t2.pred();
}
};

then go through the usual process of writing a function to obtain one.
We might also template the use of operator<.

How to do it with boost, anyone?
sort(groupA.begin(), groupA.end(), less_age());

With mine you'd put in make_less_mem_fun_ref( &Mytype::getAge ) as the
last parameter. Of course you need to include <algorithm> as well to
use sort.

With mine you'll write the functor once only then invoke it with
different classes, different members etc.
 
G

Gary Wessle

Daniel T. said:
Then make the age the key... (You might want to use a multi-map for
this.)

if you make the age the key, what happens if you have 2 names with the
same age, how can that be sorted out in the map, I think the new entry
will over-write the old. i.e
sam 15
jack 15

if you make the value the key then we have

map["15"]= "sam";
map["15"]= "jack";

now sam does not exist any more (a lost record)....
 
K

Kai-Uwe Bux

Gary said:
Daniel T. said:
Then make the age the key... (You might want to use a multi-map for
this.)

if you make the age the key, what happens if you have 2 names with the
same age, how can that be sorted out in the map, I think the new entry
will over-write the old. i.e
sam 15
jack 15

if you make the value the key then we have

map["15"]= "sam";
map["15"]= "jack";

now sam does not exist any more (a lost record)....

Please notice that Daniel told you to consider std::multimap instead of
std::map. Then, key-collisions are not an issue.


Best

Kai-Uwe Bux
 
D

Daniel T.

Gary Wessle <[email protected]> said:
Daniel T. said:
Then make the age the key... (You might want to use a multi-map for
this.)

if you make the age the key, what happens if you have 2 names with the
same age, how can that be sorted out in the map, I think the new entry
will over-write the old. i.e
sam 15
jack 15

if you make the value the key then we have

map["15"]= "sam";
map["15"]= "jack";

now sam does not exist any more (a lost record)....

Use a multimap and it won't be a problem. If you don't want to change
the age to the key then here is another idea...

typedef pair< string, int > Person;
typedef map< string, int > AgeMap;

bool second_less( Person left, Person right ) {
return left.second < right.second;
}

void fn( const AgeMap& ageMap )
{
vector< Person > temp( ageMap.begin(), ageMap.end() );
sort( temp.begin(), temp.end(), &second_less );
// at this point, temp will have all the elements of ageMap,
// sorted by age.
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top