I have std::multimap<string, MyObject*> dataMap;
where the keys are MyObject.name
and all MyObjects are stored in a std::vector<MyObject>
.
After filling the map I need to print the contents of dataMap
grouped by the same key, where I first need number of same keys with the help of dataMap.count(MyObject.name)
and then all the values with this key.
I was thinking of using two for loops
where the first loop iterates through "key group names" and counts all the keys that belong in this group, and the other for loop
iterates through all the keys in certain group and prints the MyObject.information
for(//iterate through group key names){
//print number of key occurences
for(//iterate through a certain group{
//print MyObject.information for all the keys in a group
}
}
The problem is, i don't really know how would implement this or rather how would I use iterators to my will. Any ideas?
EDIT: From the provided links i created this
for(std::multimap<string, MyObject*>::const_iterator itUnq = dataMap.cbegin();
itUnq != dataMap.cend(); itUnq = dataMap.upper_bound(itUnq->first)){
std::cout << dataMap.count(itUnq->second->name)
<< std::endl;
std::pair <std::multimap<string, MyObject*>::const_iterator,
std::multimap<string, MyObject*>::const_iterator> groupRange;
groupRange = dataMap.equal_range(itUnq->second->code);
//iterate through keys inside the group
for(std::multimap<string, MyObject*>::const_iterator itGroup = groupRange.first;
itGroup != groupRange.second; ++itGroup){
std::cout << itGroup->second->information
}
Comments?
From what I understand of your problem you can implement it using std::multimap::equal_range.
Something a bit like this:
#include <map>
#include <ctime>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
struct MyObject
{
std::string name;
int information;
MyObject(const std::string& name, int information)
: name(name), information(information) {}
};
int main()
{
std::srand(std::time(0));
std::vector<MyObject> dataVec;
std::multimap<std::string, MyObject*> dataMap;
// Give each object a random letter
// between A-J as a name and some data
for(auto i = 0; i < 10; ++i)
dataVec.emplace_back(std::string(1, 'A' + std::rand() % 10), i);
// Fill dataMap from dataVec
for(auto&& data: dataVec)
dataMap.emplace(data.name, &data);
// Select the correct type for calling the equal_range function
decltype(dataMap.equal_range("")) range;
// iterate through multimap's elements (by key)
for(auto i = dataMap.begin(); i != dataMap.end(); i = range.second)
{
// Get the range of the current key
range = dataMap.equal_range(i->first);
// Now print out that whole range
for(auto d = range.first; d != range.second; ++d)
std::cout << d->first << ": " << d->second->information << '\n';
}
}
If that's not precisely what you want, maybe it will still give you ideas how to solve your specific problem.