Search code examples
c++data-structureshashtablelookupunordered-map

Unordered Map with Multiple Value and it's lookup


I am working on an assignment where I have been given a large tab separated value txt file and I have to search through it using a good data structure. Now the problem I am facing is that I don't know if I am inserting the values correctly in this unordered_map with the key being a string and the values being a vector of struct. Secondly if I want to search how will it do it? For example if i enter the first ID how can i print out or access the other elements present in the struct?

Below is the sample data & code

id    effectiveTime    active    moduleId    definitionStatusId
100005    20020131    0    900000000000207008    900000000000074008
101009    20020131    1    900000000000207008    900000000000074008
102002    20020131    1    900000000000207008    900000000000074008
103007    20020131    1    900000000000207008    900000000000074008
104001    20020131    1    900000000000207008    900000000000073002
105000    20040731    0    900000000000207008    900000000000074008
106004    20020131    1    900000000000207008    900000000000074008
107008    20020131    1    900000000000207008    900000000000074008
108003    20020131    1    900000000000207008    900000000000074008
109006    20020131    1    900000000000207008    900000000000074008
110001    20020131    1    900000000000207008    900000000000074008
111002    20020131    1    900000000000207008    900000000000074008
112009    20020131    1    900000000000207008    900000000000074008
113004    20020131    1    900000000000207008    900000000000074008
114005    20020131    1    900000000000207008    900000000000074008
115006    20020131    1    900000000000207008    900000000000074008
116007    20020131    1    900000000000207008    900000000000074008
117003    20020131    1    900000000000207008    900000000000074008
118008    20020131    1    900000000000207008    900000000000074008
119000    20020731    1    900000000000207008    900000000000073002
120006    20020131    1    900000000000207008    900000000000074008
121005    20020131    1    900000000000207008    900000000000074008 

And here is the code

#include <iostream>
#include <vector>
#include <fstream>
#include <unordered_map>

using namespace std;

struct concept
{
    string id,effectiveTime,active,moduleId,definitionStatusId;
};

int main ()
{
    unordered_map<string,vector<concept>> concepts;
    ifstream conceptStream("concept.txt");
    if (!conceptStream.is_open())
    {
        cout << "Failed to open\n";
        return 0;
    }
    string id,effectiveTime,active,moduleId,definitionStatusId;
    string conceptLine;
    getline(conceptStream, conceptLine);
    while (!conceptStream.eof())
    {
        getline(conceptStream, id, '\t');
        getline(conceptStream, effectiveTime, '\t');
        getline(conceptStream, active, '\t');
        getline(conceptStream, moduleId, '\t');
        getline(conceptStream, definitionStatusId, '\n');
        concepts[id] = {{id,effectiveTime,active,moduleId,definitionStatusId}};
    }

  return 0;
}

Solution

  • You search for a value by using find. You have a value if the iterator returned isn't equal to end().

    unordered_map<string,vector<concept>>::const_iterator it = concepts.find(id);
    if (it != concepts.end()) {} //You have a value
    

    The vector you have inserted will always have one entry, so you could do away with that, but as you have it you need to get the first element of the vector.

    if (it != concepts.end())
      cout << it->second[0].id << it->second[0].effectiveTime; //etc
    

    Of course maybe you intend to see if the ID already exists and add it to the vector if it does. That will work, but maybe you should consider std::unordered_multimap as Shawn suggested, and if not, change the key type to concept as there will only ever be one element in the vector.

    If you do remove the vector the access code becomes simpler:

    if (it != concepts.end())
      cout << it->second.id << it->second.effectiveTime; //etc