tags:

views:

218

answers:

6

Hello, i am looking for a container, to contain objects like Employee (with info: name, salary, phone ....) that will be possible to once sort it by name (a..z) and other time sort it by salary for example. what is the best way to do it ? i thought about map, but then i define only 1 key to go by would appreciate every idea (not too advanced please ! )

--- update ---

I actually don't need to always maintain 2 STL containers, i would normally have 1 ( say Employees sorted by last name), and upon request, I don't mind making a new STL container, and pushing all the elements to it again, only this time to be sorted by salary, so i can print it by that order. Is it possible to create map1 with name sort, and map2 with salary sort ? if so would love further explanation \ example for defining these 2 maps. I have very little c++ knowledge ( first assignment i got )

+17  A: 

using this version of std::sort

template <class RandomAccessIterator, class Compare>
void sort( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

you can sort on whatever field(s) you want, supplying your own comparator. For instance

struct CompareSalary
{
  bool operator () ( const Employee& a, const Employee& b ) const
  {
    return a.salary < b.salary;
  }
}

Also since std::sort is compatible with all containers providing a random acess iterator, std::vector will do just fine.

stijn
I think you want `operator()`.
Philip Potter
oops you're right. fixed.
stijn
+5  A: 

Provide a functional to std::sort:

bool byName(Employee left, Employee right) {
    return left.name < right.name;
}

std::vector<Employee> employees;
std::sort(employees.begin(), employees.end(), byName);
Philip Potter
@Ferruccio, actually not this time. I'm passing a pointer to byName, not calling byName.
Philip Potter
I had just caught that and deleted my comment. I was thinking of byName as a functor. :-)
Ferruccio
Matthieu M.
@Matthieu: It very probably won't anyway. I've gotten into the habit of relying on copy elision in a lot of cases, and it doesn't usually let me down.
jalf
Matthieu M.
jalf
A: 

Basically you would want to define multiple comparator, each implemented to fulfill the different sorting criteria. The post by Philip Potter gives an example of one sorting criteria. You may want to define few more like this.

Overloading the less than operator will enable you to use the std::sort method with the first two parameters only, but you would be limited to just one sorting criteria.

Gunner
+8  A: 

If you want both the sorting criteria to be available at same time you could also look into Boost MultiIndex

Ps: But since you mentioned that you are new to c++ i would not recommend using Boost MultiIndex. Its difficult to understand its syntax

Yogesh Arora
(this is boost, not stl, but) except for adding/deleting entries (not counting the resort needed then), this is the most efficient way to access data sorted in different ways. It has a "funky" declaration, but it is not too advanced when following the documents and working with it is pretty straightforward.
stefaanv
A: 

Do you want them to be sorted at all times? Like a std::map does? (So you can access the lowest element with *(coll.begin())?) If so, what I would do is have two std::map's, each full of shared_ptr<T>'s, each of which is passed its own sorting functor, one for each sorting criteria. This way, you're not limited to a single "less-than" operator for your datatype, you get O(log n) inserts and deletes (std::map is just a binary tree), and the maps are is always sorted.

You'd have to synchronize the adding and removing to make sure they're added and removed from both maps, however.

Ken Simon
You're basically reinventing 10% of `boost::multi_index_container<T>`
MSalters
A: 

I actually don't need to always maintain 2 STL containers, i would normally have 1 ( say Employees sorted by last name), and upon request, i don't mind making a new STL container, and pushing all the elements to it again, only this time to be sorted by salary, so i can print it by that order. is it possible to create map1 with name sort, and map2 with salary sort ? if so would love further explanation \ example for defining these 2 maps. I have very little c++ knowledge ( first assignment i got )

antisane
If you want to update/clarify your question, please edit it.
MSalters