Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate through a multimap and print values grouped by key? [duplicate]

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?

like image 361
jabk Avatar asked Oct 23 '14 12:10

jabk


People also ask

How do you access values in a Multimap?

We can find all values of a key in Multimap using is member function equal_range(). It accepts the key as an argument and returns a pair of multimap iterator. This returned pair has a range that represents the entries with given key.

How do you get a Multimap key?

Use keySet() to avoid repetitions, keys() if you want repetitions. Then get the country instance via get(..) never used Multimap before , I have seen some examples with string and integer but not with a class object.

Can a Key have multiple values map C++?

Multimap is similar to a map with the addition that multiple elements can have the same keys. Also, it is NOT required that the key-value and mapped value pair have to be unique in this case.

How is Multimap sorted?

Multimap is an associative container that contains a sorted list of key-value pairs, while permitting multiple entries with the same key. Sorting is done according to the comparison function Compare , applied to the keys. Search, insertion, and removal operations have logarithmic complexity.


1 Answers

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';
    }
}

Run It Here

If that's not precisely what you want, maybe it will still give you ideas how to solve your specific problem.

like image 179
Galik Avatar answered Sep 29 '22 02:09

Galik