Search code examples
c++jsonboost

Read JSON object into vector of vectors


Given input.json:

{
    "Identifier1": {
        "height": 120,
        "metrics": [
            [
                -3, -2, -1
            ],
            [
                0, 1, 2, 3
            ]
        ]
    },
    "Identifier2": {
        "height": 130,
        "metrics": [
            [
                -3, -2, -1, -4
            ],
            [
                0, 1
            ],
            [
                5, 7
            ]
        ]
    }
}

I would like to read "Identifier2" -> "metrics" into a vector of vector of ints in my code.

I tried to follow the suggestion here and tried:

#include <boost/json.hpp>
using namespace boost::json;
#include <vector>
int main() {
    auto const jv = value_from("input.json"); // to read in the entire json file into object jv
    std::vector<std::vector<int>> metrics;
    metrics = value_to(jv);// ? What exactly should go here?
}

The code does not compile at present because metrics = value_to(jv); is syntactically wrong. How can I specify that I am interested in Identifier2 -> metrics's content?


Solution

  • The comment above is basically correct, but another issue is that the code you have to parse the JSON file does nothing of the sort. In fact it doesn't read the file at all, instead it turns the string "input.json" into an array

    Here's some working code, which parses the input, extracts the data and then prints it out.

    #include <boost/json.hpp>
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <iterator>
    
    using namespace boost::json;
    
    int main()
    {
        // parse the JSON file
        std::ifstream file("input.json");
        std::string content(std::istreambuf_iterator<char>{file}, 
            std::istreambuf_iterator<char>{});
        value jv = parse(content);
        // extract Identifier2/metrics as a 2D int vector
        auto metrics = value_to<std::vector<std::vector<int>>>(jv
           .as_object()["Identifier2"]
           .as_object()["metrics"]);
        // print the vector
        for (const auto& i : metrics)
        {
            for (int j : i)
                std::cout << j << ' ';
            std::cout << '\n';
        }
    }
    

    Output

    -3 -2 -1 -4
    0 1
    5 7
    

    As before I have no idea if this code represents good practice. This is my first time using this library.