Home > Software engineering >  convert a vector of complex numbers into a JSON array
convert a vector of complex numbers into a JSON array

Time:11-05

I need to convert a vector of complex numbers into a JSON array using the SimpleJSON library.
Next, I will be passing my complex vector over the socket in JSON format.
But SimpleJSON doesn't know how to work with vectors.

SimpleJSON's code is quite complex for me.... there are a lot of variadic templates.
How should I change the code in SimpleJSON so that I can convert my complex vector to JSON format:

#include "json.hpp"
#include <iostream>
#include <complex>

int main() {

struct {
    std::vector<std::complex<double>> Data;
} MESSAGE;

MESSAGE.Data = {{-3.2, 0.24}, {0.94, -9.3}};
}

I expect this JSON format

{
    "Data" : [ {"re": x, "im": y}, {"re": x, "im": y} ]
}

CodePudding user response:

It sounds very straightforward. Extending my comment to an answer: just iterate over your elements and add them to json object:

  std::vector<std::complex<double>> data({{-3.2, 0.24}, {0.94, -9.3}});
  json::JSON obj;
  obj["Data"] = json::Array();
  for (int i = 0; i < data.size(); i  ) {
    json::JSON num = {"re", data[i].real(), "im", data[i].imag()};
    obj["Data"][i] = num;
  }
  std::cout << obj << std::endl;

Note the unusual (for std containers) obj["Data"][i]. It looks like access out of bounds, but actually is not, because

        /// Access the elements of a JSON Array. 
        /// Accessing an out of bounds index will extend the Array.
        JSON& operator[]( unsigned index );

CodePudding user response:

You're problem can be divided into two subproblems. First we need a way to convert std::complex values to json::JSON objects. Then we need a way to convert std::vector values to json::JSON objects. Both can be done in a generic way (note that std::complex is not a class but a template). With the following function templates you should be able to convert your std::vector<std::complex<double>> into a simplejson container.

namespace json {

template<typename N>
JSON to_json(const std::complex<N>& c) {
    return {"re", c.real(), "im", c.imag() };
}

template<typename T>
JSON to_json(const std::vector<T>& vec) {
    JSON arr;
    for ( const auto& e : vec ) {
        arr.append(to_json(e));
    }
    return arr;
}

}

And use it like

std::vector<std::complex<double>> Data = {{-3.2, 0.24}, {0.94, -9.3}};
json::JSON jsonObj = {"Data", json::to_json(Data)};
std::cout << jsonObj;

which prints

{
  "Data" : [{
      "im" : 0.240000,
      "re" : -3.200000
    }, {
      "im" : -9.300000,
      "re" : 0.940000
    }]
}

You can easily expand those conversion functions. If for example you want to convert a std::vector<std::string>, just add a conversion function for std::string like the following:

JSON to_json(const std::string& s) {
    return JSON{s};
}
  • Related