Tryer
Tryer

Reputation: 4050

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?

Upvotes: 0

Views: 1900

Answers (2)

Loki Astari
Loki Astari

Reputation: 264401

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

Upvotes: 1

john
john

Reputation: 87959

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.

Upvotes: 2

Related Questions