Search code examples
c++nestedmultimap

Searching a Nested multimap for values in C++?


I am trying to search a nested MultiMap in which the outer Multimap has a string key value and the value for each key is another multimap which has strings as key value pairs within it shown like this:

 multimap<string,map<string, string>> myMultMap;
myMultMap.insert(make_pair("distinct", makeMap("noun", "This is the first definition")));
myMultMap.insert(make_pair("distinct", makeMap("verb", "This is the second definition")));
myMultMap.insert(make_pair("distinct", makeMap("adjective", "This is the third definition")));
myMultMap.insert(make_pair("book", makeMap("noun", "This is the book noun definition")));
myMultMap.insert(make_pair("book", makeMap("verb", "This is the book verb definition")));
myMultMap.insert(make_pair("other", makeMap("noun", "This is the other noun definition")));
myMultMap.insert(make_pair("dumb", makeMap("noun", "This is the dumb noun definition")));

I am trying to make it an interactive, searchable map/dictionary such that if i enter "book" it outputs the keyword "book" and the verb definition and noun definition:

Output:

book [noun]: This is the book noun definition

book [verb]: This is the book verb definition

so far i have tried using iterators and the .equals_range() method in the multimap class, and it works if i use "noun" as my second search parameter but if i search for verb nothing shows up.

pair <multimap<string, string>::iterator, multimap<string, string>::iterator> ret;

auto iter = myMultMap.find(str)->second;
ret = iter.equal_range("noun");


for (multimap<string,string>::iterator it=ret.first; it!=ret.second; ++it) {
    std::cout << str << " =>";
    std::cout << ' ' << it->second;
}
std::cout << '\n';

Any help would be much appreciated.

edit

I forgot to add that the outer multimap also has multiple definitions per each Part of speech key. myMultMap.insert(make_pair("book", makeMap("noun", "This is the 1 definition"))); myMultMap.insert(make_pair("book", makeMap("verb", "This is the book verb def1"))); myMultMap.insert(make_pair("book", makeMap("verb", "This is the book verb def 2"))); myMultMap.insert(make_pair("book", makeMap("verb", "This is the book def 1"))); myMultMap.insert(make_pair("book", makeMap("noun", "This is the book noun def 2")));


Solution

  • With these complex data structures you just have to carefully think your way through what type each element returns and how to further reference that type. It's a mental challenge to begin with but it gets easier with practice.

    I think maybe something like this is what you are after:

    void output(std::multimap<std::string, std::map<std::string, std::string>> mm, 
        std::string const& item)
    {
        auto range = mm.equal_range(item);
    
        for(auto item_iter = range.first; item_iter != range.second; ++item_iter)
            for(auto const& entry: item_iter->second)
                std::cout << item_iter->first << " [" << entry.first << "]: " << entry.second << '\n';
    }
    

    The outer layer is a std::multimap which can have duplicate keys so equal_range is the usual way to search a given key.

    That gives you a list of iterators so you loop through those. Each one dereferences to a std::pair<std::string, std::map<std::string, std::string>.

    The std::map can then be iterated through using a range based for loop as shown.