1

I have a vector of strings in the following format in C++

word1_word2_word3 : val

Here word1 can be any string in {str1, str2, str3, str4}
word2 can be any string in {anotherstr1, anotherstr2,...,anotherstr12}
and word3 can be any string in {yetanotherstr1, yetanotherstr2}

All sorts of permutations and combination of the above string can populated in the vector and will have a string value corresponding to that combination

My objective is to create a vector of map out of the string vector in the following format

anotherstr1 :  str1: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value

               str2: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
               ...
               ...
               str4: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
anotherstr2  : str1: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
               str2: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
               ...
               ...
               str4: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
.........
.........
anotherstr12 : str1: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
               str2: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value
                ...
                ...
               str4: yetanotherstr1 : its_value
                     yetanotherstr2 : its_value

All these string values are dynamic.

I tried doing this. Please find the pseudocode

for (each vector)
{
     parse_params_in_string(*i, word1, word2, word3);
     std::map outermap;
     std::map innermap;
     for(each word 1 and word3 combination)
            build_map_elements
     outermap.insert(innermap)
     ..
}

But the above code creates fresh inner map every time and appends it to outer map which is wrong. How can I append these values to the outer map?

Thanks in advance

Athul Sukumaran
  • 360
  • 4
  • 16
  • In your pseudo-code `outermap` and `innermap` have the same scope so they both will be destructed on each iteration of `for (each vector)`. And your result seems to need three levels, not two: `anotherstr1 : str1: yetanotherstr1`. It is very difficult to help without a [working](https://stackoverflow.com/help/minimal-reproducible-example) example. – Manuel Jul 12 '20 at 17:08

1 Answers1

1

Looking at your desired output, I decided to create a std::map of a std::map of a std::map with key and value being a std::string

I order to be able to test the code, we first build a std::vector of std::string and use your specified words as the input.

For the given example data, we will get a std::vector with 96 elements. So, 12 * 4 * 2 strings.

The next part is that what you want. First we split the std::string. I published already many answers on how to split a string. See for example here.

This time I will use a regex, because your question is not about splitting a string, but on how to build a dictionary.

Anyway, we fill a std::vector with the spltted up substrings using the std::sregex_token_iterator. So, finally, your words will be in this substring vector.

We will apply this operation for all std::strings in the std::vector in a simple range based for loop.

After we have back the words, we need to add the data to the map.

And here we will use the std::mapss index operator. Please read carefully about that here. And please read especially

Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.

This means, if you use the index operator, and the value is not yet in the std::map, it will be added. And, in any case, if the key was already there or was just created, a reference to that piece of data will be returned. And, for a nested map, we can of course cascade the index operator. So, in the line from the code below:

mapData[substrings[1]][substrings[0]][substrings[2]] = substrings[3];

First, the outermost data will be created and in any case, a reference will be returned. The same happens now for the next inner std::map and so on.

So filling such a nested map, can be done with a one-liner.

This is indeed a powerful operation.


Last but not least, we will print the data on the screen as requested by the OP.

We make this a little bit nice, by not repeating already shown data.

Please see the complete code below. The main part, that is important to you, is just 4 lines of code.

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <regex>
#include <map>
#include <iomanip>

// We want to build a vector of test strings
// For this we will use word pools
std::vector<std::string> word1Pool{ "str1", "str2", "str3", "str4" };
std::vector<std::string> word2Pool{ "anotherstr01",  "anotherstr02", "anotherstr03", "anotherstr04", "anotherstr05", 
    "anotherstr06","anotherstr07", "anotherstr08", "anotherstr09", "anotherstr10", "anotherstr11", "anotherstr12" };
std::vector<std::string> word3Pool{ "yetanotherstr1", "yetanotherstr2" };

// A regex to split the strings
const std::regex re{ R"([a-zA-Z0-9]+)" };


// Some driver code
int main() {

    // First, we build a string with all possible combinations of word fragments. Overall: 12*4*2 = 96
    size_t counter{};

    // Here we will build some demo source data. A vector with all combinations of the given words
    std::vector<std::string> sourceData{};

    for (const std::string& word1 : word1Pool)
        for (const std::string& word2 : word2Pool)
            for (const std::string& word3 : word3Pool)
                sourceData.emplace_back(word1 + "_" + word2 + "_" + word3 + " : itsvalue" + std::to_string(++counter));

    // Show the demo stings on the screen
    std::copy(sourceData.begin(), sourceData.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

    // ----------------------------------------------------------------------------------------------
    // This will be our nested map. It will hold the target data
    std::map<std::string, std::map<std::string, std::map<std::string, std::string>>> mapData;

    // Build the data in the map
    for (const std::string& line : sourceData) {

        // Split the line with demo data
        std::vector substrings(std::sregex_token_iterator(line.begin(), line.end(), re), {});

        // Add data to map
        mapData[substrings[1]][substrings[0]][substrings[2]] = substrings[3];
    }
    // ----------------------------------------------------------------------------------------------


    // Display resulting data on screen
    std::string oldKey1{}, oldKey2{}, oldKey3{};

    for (const auto& [key1, mapOuter] : mapData) {
        for (const auto [key2, mapInner] : mapOuter) {
            for (const auto [key3, dataInner] : mapInner) {


                std::cout << std::left << std::setw(12)
                    << ((oldKey1 == key1) ? std::string{} : key1) << ((oldKey1 == key1) ? "   " : " : ")  
                    << std::setw(4) 
                    << ((oldKey2 == key2) ? std::string{} : key2) << ((oldKey2 == key2) ? "  " : ": ")
                    << std::setw(14)
                    << ((oldKey3 == key3) ? std::string{} : key3) << ((oldKey3 == key3) ? "   " : " : ")
                    << dataInner << '\n';

                oldKey1 = key1;
                oldKey2 = key2;
                oldKey3 = key3;
            }
        }
    }
    return 0;
}

Vector with test strings:

str1_anotherstr01_yetanotherstr1 : itsvalue1
str1_anotherstr01_yetanotherstr2 : itsvalue2
str1_anotherstr02_yetanotherstr1 : itsvalue3
str1_anotherstr02_yetanotherstr2 : itsvalue4
str1_anotherstr03_yetanotherstr1 : itsvalue5
str1_anotherstr03_yetanotherstr2 : itsvalue6
str1_anotherstr04_yetanotherstr1 : itsvalue7
str1_anotherstr04_yetanotherstr2 : itsvalue8
str1_anotherstr05_yetanotherstr1 : itsvalue9
str1_anotherstr05_yetanotherstr2 : itsvalue10
str1_anotherstr06_yetanotherstr1 : itsvalue11
str1_anotherstr06_yetanotherstr2 : itsvalue12
str1_anotherstr07_yetanotherstr1 : itsvalue13
str1_anotherstr07_yetanotherstr2 : itsvalue14
str1_anotherstr08_yetanotherstr1 : itsvalue15
str1_anotherstr08_yetanotherstr2 : itsvalue16
str1_anotherstr09_yetanotherstr1 : itsvalue17
str1_anotherstr09_yetanotherstr2 : itsvalue18
str1_anotherstr10_yetanotherstr1 : itsvalue19
str1_anotherstr10_yetanotherstr2 : itsvalue20
str1_anotherstr11_yetanotherstr1 : itsvalue21
str1_anotherstr11_yetanotherstr2 : itsvalue22
str1_anotherstr12_yetanotherstr1 : itsvalue23
str1_anotherstr12_yetanotherstr2 : itsvalue24
str2_anotherstr01_yetanotherstr1 : itsvalue25
str2_anotherstr01_yetanotherstr2 : itsvalue26
str2_anotherstr02_yetanotherstr1 : itsvalue27
str2_anotherstr02_yetanotherstr2 : itsvalue28
str2_anotherstr03_yetanotherstr1 : itsvalue29
str2_anotherstr03_yetanotherstr2 : itsvalue30
str2_anotherstr04_yetanotherstr1 : itsvalue31
str2_anotherstr04_yetanotherstr2 : itsvalue32
str2_anotherstr05_yetanotherstr1 : itsvalue33
str2_anotherstr05_yetanotherstr2 : itsvalue34
str2_anotherstr06_yetanotherstr1 : itsvalue35
str2_anotherstr06_yetanotherstr2 : itsvalue36
str2_anotherstr07_yetanotherstr1 : itsvalue37
str2_anotherstr07_yetanotherstr2 : itsvalue38
str2_anotherstr08_yetanotherstr1 : itsvalue39
str2_anotherstr08_yetanotherstr2 : itsvalue40
str2_anotherstr09_yetanotherstr1 : itsvalue41
str2_anotherstr09_yetanotherstr2 : itsvalue42
str2_anotherstr10_yetanotherstr1 : itsvalue43
str2_anotherstr10_yetanotherstr2 : itsvalue44
str2_anotherstr11_yetanotherstr1 : itsvalue45
str2_anotherstr11_yetanotherstr2 : itsvalue46
str2_anotherstr12_yetanotherstr1 : itsvalue47
str2_anotherstr12_yetanotherstr2 : itsvalue48
str3_anotherstr01_yetanotherstr1 : itsvalue49
str3_anotherstr01_yetanotherstr2 : itsvalue50
str3_anotherstr02_yetanotherstr1 : itsvalue51
str3_anotherstr02_yetanotherstr2 : itsvalue52
str3_anotherstr03_yetanotherstr1 : itsvalue53
str3_anotherstr03_yetanotherstr2 : itsvalue54
str3_anotherstr04_yetanotherstr1 : itsvalue55
str3_anotherstr04_yetanotherstr2 : itsvalue56
str3_anotherstr05_yetanotherstr1 : itsvalue57
str3_anotherstr05_yetanotherstr2 : itsvalue58
str3_anotherstr06_yetanotherstr1 : itsvalue59
str3_anotherstr06_yetanotherstr2 : itsvalue60
str3_anotherstr07_yetanotherstr1 : itsvalue61
str3_anotherstr07_yetanotherstr2 : itsvalue62
str3_anotherstr08_yetanotherstr1 : itsvalue63
str3_anotherstr08_yetanotherstr2 : itsvalue64
str3_anotherstr09_yetanotherstr1 : itsvalue65
str3_anotherstr09_yetanotherstr2 : itsvalue66
str3_anotherstr10_yetanotherstr1 : itsvalue67
str3_anotherstr10_yetanotherstr2 : itsvalue68
str3_anotherstr11_yetanotherstr1 : itsvalue69
str3_anotherstr11_yetanotherstr2 : itsvalue70
str3_anotherstr12_yetanotherstr1 : itsvalue71
str3_anotherstr12_yetanotherstr2 : itsvalue72
str4_anotherstr01_yetanotherstr1 : itsvalue73
str4_anotherstr01_yetanotherstr2 : itsvalue74
str4_anotherstr02_yetanotherstr1 : itsvalue75
str4_anotherstr02_yetanotherstr2 : itsvalue76
str4_anotherstr03_yetanotherstr1 : itsvalue77
str4_anotherstr03_yetanotherstr2 : itsvalue78
str4_anotherstr04_yetanotherstr1 : itsvalue79
str4_anotherstr04_yetanotherstr2 : itsvalue80
str4_anotherstr05_yetanotherstr1 : itsvalue81
str4_anotherstr05_yetanotherstr2 : itsvalue82
str4_anotherstr06_yetanotherstr1 : itsvalue83
str4_anotherstr06_yetanotherstr2 : itsvalue84
str4_anotherstr07_yetanotherstr1 : itsvalue85
str4_anotherstr07_yetanotherstr2 : itsvalue86
str4_anotherstr08_yetanotherstr1 : itsvalue87
str4_anotherstr08_yetanotherstr2 : itsvalue88
str4_anotherstr09_yetanotherstr1 : itsvalue89
str4_anotherstr09_yetanotherstr2 : itsvalue90
str4_anotherstr10_yetanotherstr1 : itsvalue91
str4_anotherstr10_yetanotherstr2 : itsvalue92
str4_anotherstr11_yetanotherstr1 : itsvalue93
str4_anotherstr11_yetanotherstr2 : itsvalue94
str4_anotherstr12_yetanotherstr1 : itsvalue95
str4_anotherstr12_yetanotherstr2 : itsvalue96

Output:

anotherstr01 : str1: yetanotherstr1 : itsvalue1
                     yetanotherstr2 : itsvalue2
               str2: yetanotherstr1 : itsvalue25
                     yetanotherstr2 : itsvalue26
               str3: yetanotherstr1 : itsvalue49
                     yetanotherstr2 : itsvalue50
               str4: yetanotherstr1 : itsvalue73
                     yetanotherstr2 : itsvalue74
anotherstr02 : str1: yetanotherstr1 : itsvalue3
                     yetanotherstr2 : itsvalue4
               str2: yetanotherstr1 : itsvalue27
                     yetanotherstr2 : itsvalue28
               str3: yetanotherstr1 : itsvalue51
                     yetanotherstr2 : itsvalue52
               str4: yetanotherstr1 : itsvalue75
                     yetanotherstr2 : itsvalue76
anotherstr03 : str1: yetanotherstr1 : itsvalue5
                     yetanotherstr2 : itsvalue6
               str2: yetanotherstr1 : itsvalue29
                     yetanotherstr2 : itsvalue30
               str3: yetanotherstr1 : itsvalue53
                     yetanotherstr2 : itsvalue54
               str4: yetanotherstr1 : itsvalue77
                     yetanotherstr2 : itsvalue78
anotherstr04 : str1: yetanotherstr1 : itsvalue7
                     yetanotherstr2 : itsvalue8
               str2: yetanotherstr1 : itsvalue31
                     yetanotherstr2 : itsvalue32
               str3: yetanotherstr1 : itsvalue55
                     yetanotherstr2 : itsvalue56
               str4: yetanotherstr1 : itsvalue79
                     yetanotherstr2 : itsvalue80
anotherstr05 : str1: yetanotherstr1 : itsvalue9
                     yetanotherstr2 : itsvalue10
               str2: yetanotherstr1 : itsvalue33
                     yetanotherstr2 : itsvalue34
               str3: yetanotherstr1 : itsvalue57
                     yetanotherstr2 : itsvalue58
               str4: yetanotherstr1 : itsvalue81
                     yetanotherstr2 : itsvalue82
anotherstr06 : str1: yetanotherstr1 : itsvalue11
                     yetanotherstr2 : itsvalue12
               str2: yetanotherstr1 : itsvalue35
                     yetanotherstr2 : itsvalue36
               str3: yetanotherstr1 : itsvalue59
                     yetanotherstr2 : itsvalue60
               str4: yetanotherstr1 : itsvalue83
                     yetanotherstr2 : itsvalue84
anotherstr07 : str1: yetanotherstr1 : itsvalue13
                     yetanotherstr2 : itsvalue14
               str2: yetanotherstr1 : itsvalue37
                     yetanotherstr2 : itsvalue38
               str3: yetanotherstr1 : itsvalue61
                     yetanotherstr2 : itsvalue62
               str4: yetanotherstr1 : itsvalue85
                     yetanotherstr2 : itsvalue86
anotherstr08 : str1: yetanotherstr1 : itsvalue15
                     yetanotherstr2 : itsvalue16
               str2: yetanotherstr1 : itsvalue39
                     yetanotherstr2 : itsvalue40
               str3: yetanotherstr1 : itsvalue63
                     yetanotherstr2 : itsvalue64
               str4: yetanotherstr1 : itsvalue87
                     yetanotherstr2 : itsvalue88
anotherstr09 : str1: yetanotherstr1 : itsvalue17
                     yetanotherstr2 : itsvalue18
               str2: yetanotherstr1 : itsvalue41
                     yetanotherstr2 : itsvalue42
               str3: yetanotherstr1 : itsvalue65
                     yetanotherstr2 : itsvalue66
               str4: yetanotherstr1 : itsvalue89
                     yetanotherstr2 : itsvalue90
anotherstr10 : str1: yetanotherstr1 : itsvalue19
                     yetanotherstr2 : itsvalue20
               str2: yetanotherstr1 : itsvalue43
                     yetanotherstr2 : itsvalue44
               str3: yetanotherstr1 : itsvalue67
                     yetanotherstr2 : itsvalue68
               str4: yetanotherstr1 : itsvalue91
                     yetanotherstr2 : itsvalue92
anotherstr11 : str1: yetanotherstr1 : itsvalue21
                     yetanotherstr2 : itsvalue22
               str2: yetanotherstr1 : itsvalue45
                     yetanotherstr2 : itsvalue46
               str3: yetanotherstr1 : itsvalue69
                     yetanotherstr2 : itsvalue70
               str4: yetanotherstr1 : itsvalue93
                     yetanotherstr2 : itsvalue94
anotherstr12 : str1: yetanotherstr1 : itsvalue23
                     yetanotherstr2 : itsvalue24
               str2: yetanotherstr1 : itsvalue47
                     yetanotherstr2 : itsvalue48
               str3: yetanotherstr1 : itsvalue71
                     yetanotherstr2 : itsvalue72
               str4: yetanotherstr1 : itsvalue95
                     yetanotherstr2 : itsvalue96
A M
  • 14,694
  • 5
  • 19
  • 44