How to save a vector of a custom type of elements on disk, read it, and parse it into a vector again using C++ - c++

The vector type is TrackInfo:
class TrackInfo
{
public:
TrackInfo(URL& _url, String& _title, double& _length, String _fileFormat);
URL url;
String title;
double length;
String fileFormat;
};
====================================================================================
std::vector<TrackInfo> tracks;
TrackInfo track(fileURL, fileName, length, fileFormat);
tracks.push_back(track);
tracks.push_back(track);
So, how can I save this vector on the computer and then reread it when I need and convert the file into the same vector again?

I used nlohmann JSON. You can find it here -> https://json.nlohmann.me/
My code:
std::vector<TrackInfo> StoreData::jsonToTrackInfo(json jsonFile)
{
std::vector<TrackInfo> tracks;
for (json jsonf : jsonFile["Playlist"])
{
// Try to parse the data. If there is an error, return the empty vector.
// If one of the Playlist tracks has a problem, it won't be parsed and will parse the rest of the playlist.
try
{
String urlString = jsonf["url"];
String title = jsonf["title"];
double length = jsonf["length"];
String format = jsonf["format"];
URL url { urlString };
TrackInfo track(url, title, length, format);
tracks.push_back(track);
}
catch (const std::exception&)
{
//..
}
}
return tracks;
}
json StoreData::trackInfoToJson(std::vector<TrackInfo> tracks)
{
json j;
// Convert each track into JSON data.
for (TrackInfo track : tracks)
{
j.push_back(
{
{"url" , track.url.toString(false).toStdString()},
{"title" , track.title.toStdString() },
{"length", track.length},
{"format", track.fileFormat.toStdString()}
}
);
}
json jsonFile;
jsonFile["Playlist"] = j;
return jsonFile; // return the Json File
}
and the output of the JSON file should look like this:
{
"Playlist": [
{
"format": ".mp3",
"length": 106.0,
"title": "c_major_theme.mp3",
"url": "file:///C%3A/Users/me/Desktop/tracks/c_major_theme.mp3"
},
{
"format": ".mp3",
"length": 84.0,
"title": "fast_melody_regular_drums.mp3",
"url": "file:///C%3A/Users/me/Desktop/tracks/fast_melody_regular_drums.mp3"
}
]
}
You can find helpful examples here on their website: https://json.nlohmann.me/api/basic_json/#non-member-functions
I hope you find this a helpful answer :D

Related

Perform operation on first element and then all items of list in java stream

I want to iterate a list of object 2 times. First time I need to use only first object and perform some operation. Second time I want to perform operation on all the items of list.
In below example, I have list of TestPojo i.e. testPojoList.
Using Java stream I have tried to achieve the same in 2 steps (Operation#1 and Operation#2) Is there any better way or I can merge both of the operations in single operation? below is the piece of code:
public void Mapping() {
TestPojo testPojo1 = TestPojo.builder().name("Mike").city("Denver").company("Tesla").build();
TestPojo testPojo2 = TestPojo.builder().name("Bob").city("Atlanta").company("Tesla").build();
TestPojo testPojo3 = TestPojo.builder().name("Steve").city("Chicago").company("Tesla").build();
TestPojo testPojo4 = TestPojo.builder().name("John").city("Boston").company("Tesla").build();
List<TestPojo> testPojoList = Arrays.asList(testPojo1, testPojo2, testPojo3, testPojo4);
//Operation1
TransformedTestPojo transformedTestPojo = testPojoList.stream().findFirst().map(testPojo -> mapCompanyName(testPojo)).orElse(null);
//Operation2
List<PersonalDetails> personalDetailsList = testPojoList.stream().map(testPojo -> mapOtherDetails(testPojo)).collect(Collectors.toList());,
transformedTestPojo.setPersonalDetailsList(personalDetailsList);
System.out.println(transformedTestPojo);
}
private PersonalDetails mapOtherDetails(TestPojo testPojo) {
return PersonalDetails.builder().name(testPojo.getName()).City(testPojo.getCity()).build();
}
private TransformedTestPojo mapCompanyName(TestPojo testPojo) {
return TransformedTestPojo.builder().company(testPojo.getCompany()).build();
}
public class TestPojo {
String name;
String city;
String company;
}
public class TransformedTestPojo {
String company;
List<PersonalDetails> personalDetailsList;
}
public class PersonalDetails {
String name;
String City;
}
Following will be the output:
//Request List
{
"testPojoList": [
{
"name": "Mike",
"city": "Denver",
"company": "Tesla"
},
{
"name": "Bob",
"city": "Atlanta",
"company": "Tesla"
},
{
"name": "Steve",
"city": "Chicago",
"company": "Tesla"
},
{
"name": "John",
"city": "Boston",
"company": "Tesla"
}
]
}
//Response Object
"TransformedTestPojo":
{
"company": "Tesla",
"personalDetailsList": [
{
"name": "Mike",
"City": "Denver"
},
{
"name": "Bob",
"City": "Atlanta"
},
{
"name": "Steve",
"City": "Chicago"
},
{
"name": "John",
"City": "Boston"
}
]
}
Here are two ways to do it. But first, I created the classes. Instead of a builder I used a constructor for TestPojo. But it will still work.
class TestPojo {
String name;
String city;
String company;
public TestPojo(String name, String city, String company) {
this.name = name;
this.city = city;
this.company = company;
}
public String getName() {
return name;
}
public String getCity() {
return city;
}
public String getCompany() {
return company;
}
#Override
public String toString() {
return String.format("[%s, %s, %s]", name, city, company);
}
}
class TransformedTestPojo {
String company;
List<PersonalDetails> personalDetailsList;
public TransformedTestPojo(String company,
List<PersonalDetails> personalDetailsList) {
this.company = company;
this.personalDetailsList = personalDetailsList;
}
public String getCompany() {
return company;
}
public List<PersonalDetails> getPersonalDetailsList() {
return personalDetailsList;
}
}
class PersonalDetails {
String name;
String City;
public PersonalDetails(String name, String city) {
this.name = name;
City = city;
}
#Override
public String toString() {
return String.format("[%s, %s]", name, City);
}
}
The Data
List<TestPojo> testPojoList =
List.of(new TestPojo("Mike", "Denver", "Tesla"),
new TestPojo("Bob", "Atlanta", "Tesla"),
new TestPojo("Steve", "Chicago", "Tesla"),
new TestPojo("John", "Boston", "Tesla"));
The Map approach using a loop
The best approach (imo) is to use Java 8 features of the Map interface
allocate a map
Iterate over the testPojoList
Map.compute will take a key, and then if the value is null, create one. Otherwise, it uses the existing value.
that value is returned and can be used in the same construct to further modify the value. In this case it does the following:
create a new TransformedTestPojo instance with the key (company) and new ArrayList<>() for the personal details.
then return that list and get the personal details list and add a new Personal details instance.
Map<String, TransformedTestPojo> map = new HashMap<>();
for (TestPojo tp : testPojoList) {
map.compute(tp.getCompany(),
(k, v) -> v == null ? new TransformedTestPojo(k,
new ArrayList<>()) : v)
.getPersonalDetailsList().add(new PersonalDetails(
tp.getName(), tp.getCity()));
}
Once the map has been created, get the map values (which has the TransformedTestPojo instances) and return as a collection.
Collection<TransformedTestPojo> collection = map.values();
Note that a Collection (super type of List) , not a List is created. If a list is required you can do the following.
List<TransformedTestPojo> list = new ArrayList<>(map.values());
Displaying the results
list.forEach(k -> {
System.out.println(k.getCompany());
k.getPersonalDetailsList()
.forEach(p -> System.out.println(" " + p));
});
prints
Tesla
[Mike, Denver]
[Bob, Atlanta]
[Steve, Chicago]
[John, Boston]
Here is a stream solution.
stream the testPojoList
Use Collectors.groupingBy with company as the key
The associated list will be of PersonalDetails instances.
then stream the entrySet of the map and build a list of TransformedTestPojo
List<TransformedTestPojo> list1 = testPojoList.stream()
.collect(Collectors.groupingBy(TestPojo::getCompany,
Collectors.mapping(
tp -> new PersonalDetails(
tp.getName(), tp.getCity()),
Collectors.toList())))
.entrySet().stream()
.map(e -> new TransformedTestPojo(e.getKey(),
e.getValue()))
.toList();
}
Note that the map itself could be used instead of a returned List<TransformedTestPojo>. The key is the company name and the value contains the list of PersonalDetails. If that is useful, then all you need is the following:
Map<String, List<PersonalDetails>> result = testPojoList.stream()
.collect(Collectors.groupingBy(TestPojo::getCompany,
Collectors.mapping(
tp -> new PersonalDetails(
tp.getName(), tp.getCity()),
Collectors.toList())))

libbson help to read data into object C++

i have my unreal project that must read out some BSON document data into a map.
right now i'm able to load that file and print it out with the following code :
void AMyActor::BeginPlay()
{
Super::BeginPlay();
std::ifstream input( filePath , std::ios::binary );
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
bson_t* doc{ bson_new_from_data(buffer.data(),buffer.size()) };
char *str;
if( doc != nullptr )
{
UE_LOG(LogTemp,Warning,TEXT( "Success" ));
str = bson_as_json(doc, NULL);
FString fstr = FString(UTF8_TO_TCHAR(str));
UE_LOG(LogTemp, Warning, TEXT("BSON Output: %s"), *fstr);
}
}
and this is here is where i want to store it :
class Databases
{
std::map<std::string,DatabaseBase> _dictionary;
explicit Databases(const std::map<std::string, DatabaseBase>& dictionary)
: _dictionary(dictionary)
{
}
};
so what i'm looking for is to create a new instance of Databases and initialize "_dictionary" with the content of the bson document.
i'm actually looking for this into the libbson document : http://mongoc.org/libbson/current/bson_t.html
but without success...anyone can help me?
thank's in advance
PS: i'm under unreal but i have linked the libbson library
Update:
since i have to provide how my json file looks like, and DatabaseBase looks like
JSON :
{
"_dictionary" : [ {
"_classID" : "CC00",
"_dictionary" : [ {
"k" : "sample_key",
"v" : ["ACH_00"]
}, {
"k" : "sample_index",
"v" : ["0"]
}]
}, {
"_classID" : "CC01",
"_dictionary" : [ {
"k" : "sample_key",
"v" : ["ACH_01"]
}, {
"k" : "sample_index",
"v" : ["1"]
}]
}]
}
DatabaseBase :
class DatabaseBase
{
public:
DatabaseBase() = default;
std::string sample_key;
int sample_index;
};
Breaking out nlohmann::json:
using nlohmann::json;
std::map<std::string, DatabaseBase> dictionaries;
json input = json::from_bson(buffer);
for (auto& obj : input["_dictionary"]) {
auto name = obj["_classID"];
auto key = obj["_dictionary"][0]["v"][0];
auto idx = stoi(obj["_dictionary"][1]["v"][0].get<std::string>());
auto db = DatabaseBase{key, idx};
dictionaries[name] = db;
}
Databases dbs{dictionaries};
output: (from my debugger)
(lldb) p dbs
(Databases) $0 = {
_dictionary = size=2 {
[0] = {
first = "CC00"
second = (sample_key = "ACH_00", sample_index = 0)
}
[1] = {
first = "CC01"
second = (sample_key = "ACH_01", sample_index = 1)
}
}
}

How to Set Specific Dimension of Profile Picture in Facebook Graph Api Request?

I tried to set params to picture.width(360).height(360)
const infoRequest = new GraphRequest(
'/me',
{
accessToken: tokenData.accessToken,
parameters: {
fields: {
string: 'id,email,name,picture.width(360).height(360)'
}
}
},
responseInfoCallback
);
but it returns an incorrect dimension 480x480
{
"profile":{
"picture":{
"data":{
"width":480,
"height":480,
"url":"https://scontent.fmnl3-1.fna.fbcdn.net/v/t1.30497-1/c141.0.480.480a/p480x480/84628273_176159830277856_972693363922829312_n.jpg?_nc_cat=1&_nc_sid=12b3be&_nc_eui2=AeF95aCnm2ggUPNPmTv9zCouik--Qfnh2B6KT75B-eHYHvMDChmr6ZbCJUK-KjNtt6PEAlHLBWx9GsGneBpfz-Jm&_nc_ohc=VQqsNSqP_MgAX_0Hjw6&_nc_ht=scontent.fmnl3-1.fna&oh=f11455cd5e09ac5466f5b7590d489e7e&oe=5EDF5715",
"is_silhouette":true
}
},
"id":"102794254765525",
"name":"Elizabeth Aleajdheafejh Fallerwitz",
"email":"swgqsfetew_1588681446#tfbnw.net"
}
}
any help would be much appreciated
You can use this .
const user = {
"name": getUser.name,
"firstName":getUser.first_name,
"lastName": getUser.last_name,
// "profileImage": getUser.picture.data.url,
profileImage:`http://graph.facebook.com/${getUser.id}/picturetype=large&redirect=true&width=500&height=500`,
"token": data.accessToken,
}
if any problem you may ask.

How to extract JSON Array From json in mulesoft

I am getting xml output then i am converting that xml into json object.the format is given below.
{
"SOAP-ENV:Envelope": {
"#xmlns:SOAP-ENV": "http://schemas.xmlsoap.org/soap/envelope/",
"#xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"#xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
"SOAP-ENV:Body": {
"rpc:TestExampleResponse": {
"#xmlns:rpc": "http://Test.com/asi/",
"TestMessage": {
"listOfTESTS": {
"#xmlns:xmlns": "http://www.Test.com/xml/TEST",
"TESTS": [{
"id": "1",
"lastSyncDate": "12/16/2015 07:06:38",
"listOfTESTsyncrealtimeChild": null
}, {
"id": "2",
"lastSyncDate": "12/16/2015 07:06:38",
"listOfTESTsyncrealtimeChild": null
}
]
}
}
}
}
}
}
i want to extract Test array from JSON Output in Mulesoft.I dont know how to extract that array in mulesoft.Thanks in advance
You can use Dataweave (Transform Message component in Anypoint Studio)
(Mule EE)
Take a look to the documentation:
https://docs.mulesoft.com/mule-user-guide/v/3.7/using-dataweave-in-studio
Sample script for your input:
%dw 1.0
%input payload application/json
%output application/json
---
TESTS: payload."SOAP-ENV:Envelope"."SOAP-ENV:Body"."rpc:TestExampleResponse".TestMessage.listOfTESTS.TESTS map ((tEST , indexOfTEST) -> {
id: tEST.id,
lastSyncDate: tEST.lastSyncDate,
listOfTESTsyncrealtimeChild: tEST.listOfTESTsyncrealtimeChild
})
Output when using %output application/json:
{
"TESTS": [
{
"id": "1",
"lastSyncDate": "12/16/2015 07:06:38",
"listOfTESTsyncrealtimeChild": null
},
{
"id": "2",
"lastSyncDate": "12/16/2015 07:06:38",
"listOfTESTsyncrealtimeChild": null
}
]
}
Output when using %output application/java:
{TESTS=[{id=1, lastSyncDate=12/16/2015 07:06:38, listOfTESTsyncrealtimeChild=null}, {id=2, lastSyncDate=12/16/2015 07:06:38, listOfTESTsyncrealtimeChild=null}]}
You can write a custom transformer like below. This transformer uses Jackson (com.fasterxml.jackson) dependency.
The transformer returns a list of strings where each string represents an element of your TESTS array.
public class JsonArrayExtractor extends AbstractTransformer {
private final ObjectMapper mapper = new ObjectMapper();
private final String testsNodeJsonPointer = "/SOAP-ENV:Envelope/SOAP-ENV:Body/rpc:TestExampleResponse/TestMessage/listOfTESTS/TESTS";
public JsonArrayExtractor() {
registerSourceType(DataTypeFactory.STRING);
}
#Override
protected Object doTransform(Object src, String enc) throws TransformerException {
String payload = Objects.toString(src);
JsonNode root;
try {
root = mapper.readTree(payload);
} catch (IOException e) {
throw new TransformerException(this, e);
}
List<String> testsList = new ArrayList<>();
JsonNode testsNode = root.at(JsonPointer.valueOf(testsNodeJsonPointer));
if (testsNode instanceof ArrayNode) {
ArrayNode testsArrayNode = (ArrayNode) testsNode;
for (JsonNode test : testsArrayNode) {
testsList.add(test.toString());
}
}
return testsList;
}
}
And you can use the above transformer in your flow as below.
<custom-transformer class="org.ram.JsonArrayExtractor" doc:name="extractTestsArray"/>

Creating an array of structures using libJson

I'm using libJson (C++ library) for parsing a JSON file. My JSON files looks as follows.
{
"Comany":
{
"name": "Some Company",
"Resources": {
"employees": [
{"name": "John", "id": "23432"},
{"name": "Alex", "id": "32432"}
],
"Computers": [
{"IPAddress": "192.168.1.3", "CPU": "IntelCorei5"},
{"IPAddress": "192.168.1.4", "CPU": "IntelCorei3"}
]
}
}
}
I have structs for Employee and Computer. I would like to create an array of structures.
Any ideas how this can be done with libJson?
Pakal Persist looks like a perfect fit for what you are trying to do.
since there is no reflection in c++ the only extra thing you have to do is to add a member function.
#include "JsonReader.h"
struct Computer
{
std::string IPAddress;
std::string CPU;
void persist(Archive* archive)
{
a->value("IPAddress",IPAddress);
a->value("CPU",CPU);
}
}
struct Employee
{
std::string name;
int id;
void persist(Archive* archive)
{
a->value("name",name);
a->value("id",id);
}
}
struct Resources
{
std::vector<Employee> employees;
std::vector<Computer*> Computers;
void persist(Archive* archive)
{
archive->value("employees","employee",employees);
archive->value("Computers","computer",Computers);
}
}
struct Company
{
std::string name;
Resources resources;
void persist(Archive* a)
{
a->value("name",name);
a->value("Resources",resources);
}
}
Company company;
JsonReader reader;
reader.read("company.json","Company",company);