skip to Main Content

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?

2

Answers


  1. 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.

    Login or Signup to reply.
  2. I would use ThorsSerializer (Small note I am the author). Code would look like this:

    #include <iostream>
    #include <sstream>
    #include "ThorSerialize/Traits.h"
    #include "ThorSerialize/JsonThor.h"
    
    class Person
    {
        friend class ThorsAnvil::Serialize::Traits<Person>;
        int                           height;
        std::vector<std::vector<int>> metrics;
        public:
    };
    
    // Declare the traits.
    // Specifying what members need to be serialized.
    ThorsAnvil_MakeTrait(Person, height, metrics);
    
    int main()
    {
        using ThorsAnvil::Serialize::jsonImporter;
        using ThorsAnvil::Serialize::jsonExporter;
    
        std::map<std::string, Person>   data;
    
        std::cin >> jsonImporter(data);
    }
    

    Compiled with:

    g++ -std=c++17 main.cpp -I /opt/homebrew/include/ -L /opt/homebrew/lib/ -lThorSerialize17 -lThorsLogging17

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search