Search code examples
c++booststlmultimap

How to create table of grouped multimap key and associated values in c++


In below code I am grouping the multimap key with associated values using equal_range after insertion the elements in map based on Group1 and Group2. As per my requirement I need to set these values in API interface based on key value association in below format.

i.e.

     {"group1","pointcloud_min_z", "int_t","24"};
     {"group1","pointcloud_max_z", "bool_t","true"};
     {"group2","pointcloud_max_z", "double_t","13"};
     {"group2","pointcloud_min_z", "double_t","20.0"};

Now the question is how to create table based on multiple grouped key data. in this scenario column is going to be always constant but based on data insertion/deletion in multimap rows will be added/removed. Here group1 and group2 are keys. kindly suggest selection of container and approach to convert the group in to table.

Code snippet

#include <iostream>
#include <string>
#include <map>
using namespace std;

typedef multimap<string, string> StringToIntMap;
typedef StringToIntMap::iterator mapIter;

int main ()
{
    StringToIntMap mymap;

    mymap.insert(make_pair("Group2", "pointcloud_max_z"));
    mymap.insert(make_pair("Group1",  "pointcloud_min_z"));
    mymap.insert(make_pair("Group2", "double_t"));
    mymap.insert(make_pair("Group1",  "int_t"));
    mymap.insert(make_pair("Group2", "13"));
    mymap.insert(make_pair("Group1",  "pointcloud_min_z"));
    mymap.insert(make_pair("Group2",  "pointcloud_min_z"));
    mymap.insert(make_pair("Group1",  "bool_t"));
    mymap.insert(make_pair("Group1",  "true"));
    mymap.insert(make_pair("Group1",  "pointcloud_min_max_z"));

    cout << "mymap contains:" << endl;

    mapIter m_it, s_it;

    for (m_it = mymap.begin();  m_it != mymap.end();  m_it = s_it)
    {
        string theKey = (*m_it).first;

        cout << endl;
        cout << "  key = '" << theKey << "'" << endl;

        pair<mapIter, mapIter> keyRange = mymap.equal_range(theKey);

        // Iterate over all map elements with key == theKey

        for (s_it = keyRange.first;  s_it != keyRange.second;  ++s_it)
        {
           cout << "    value = " << (*s_it).second << endl;
        }
    }

    return 0;

}   //  end main

enter code here

Solution

  • From your question it appears you want to store the records in the format (key,value). For this you can encapsulate the non-key columns in an object and store it in a multimap like (key, object*).

    I have modified your code for the same as given below-

    class DATA
    {
    public:
       //control access to data members as needed
       string name;
       string type;
       string value;
    
       DATA(string name, string type, string value): name(name), type(type), value(value) {}   
     };
    
    typedef multimap<string, DATA*> StringToIntMap;
    typedef StringToIntMap::iterator mapIter;
    
    int main ()
    {
        StringToIntMap mymap;
    
        //insert record {"group1","pointcloud_min_z", "int_t","24"}
        DATA *elem = new DATA("pointcloud_min_z", "int_t","24");
        mymap.insert(make_pair("Group1", elem));
        //insert record {"group1","pointcloud_max_z", "bool_t","true"}
        elem = new DATA("pointcloud_max_z", "bool_t","true");
        mymap.insert(make_pair("Group1", elem));
        //insert record {"group2","pointcloud_max_z", "double_t","13"}
        elem = new DATA("pointcloud_max_z", "double_t","13");
        mymap.insert(make_pair("Group2", elem));
        //insert record {"group2","pointcloud_min_z", "double_t","20.0"}
        elem = new DATA("pointcloud_min_z", "double_t","20.0");
        mymap.insert(make_pair("Group2", elem));
    
        cout << "mymap contains:" << endl;
    
        mapIter m_it, s_it;
    
        for (m_it = mymap.begin();  m_it != mymap.end();  m_it = s_it)
        {
            string theKey = (*m_it).first;
    
            cout << endl;
            cout << "  key = '" << theKey << "'" << endl;
    
            pair<mapIter, mapIter> keyRange = mymap.equal_range(theKey);
    
            // Iterate over all map elements with key == theKey
    
            for (s_it = keyRange.first;  s_it != keyRange.second;  ++s_it)
            {
               cout << "    value = " << (*s_it).second->name << ", " 
                    << (*s_it).second->type << ", " 
                    << (*s_it).second->value << endl;
            }
        }
    
        //when done delete the record pointers from the multimap
        return 0;
    
    }   //  end main