Nested maps in Qt's QCborStreamWriter? - qt

My program provides a large amount of data, organized in nested maps, that I would like to serialize and write in a file. Originally, I used a QJsonDocument with QJsonMap's and QJsonArray's, but the file writing process at the end is very long and the file too large (>400MB). So I looked into QCborStreamWriter but I can't find examples with nested maps.
Is there a way to do it ?
QCborStreamWriter::append() does not take a QCborMap as argument.
QCborStreamWriter writer;
writer.startArray();
QCBorMap map;
writer.append(map); <= not accepted
writer.endArray();

Calling repeatedly startMap() and endMap() seems to do the trick.
QCborStreamWriter writer(&file);
writer.startMap();
writer.append("A");
writer.append(1);
writer.append("B");
writer.append(2);
writer.append("C");
writer.startMap(); // start nested map
writer.append("C1");
writer.append(3.1);
writer.append("C2");
writer.append(3.2);
writer.append("C3");
writer.append(3.3);
writer.endMap(); // end nested map
writer.endMap();
and produces the following tree:
{
"A": 1,
"B": 2,
"C": {
"C1": 3.1,
"C2": 3.2,
"C3": 3.3
},
"D": 4
}

Related

Godot 3.4: Quest System using Dictionaries

I took this to the Godot Reddit first, but honestly it's not much help imo. A lot of questions go unanswered there. So here I am.
As the title says, Im making a quest system in godot 2d using nested dictionaries. Ive seen people use Nodes, Classes or otherwise for their quest systems, and a few dictionary based ones out there. I chose dictionaries as I know them the best(still isnt a whole lot, or i probably wouldnt be here asking this lol) And my quest system is set up like so:
QuestBase --> QuestHandler --> PlayerData
QuestBase is a giant dictionary of all available quests in the game.
PlayerData is a giant dictionary of all the player stats(including active, completed, or failed quests)
and QuestHandler takes a questName in a function to Copy the quest(questName) from QuestBase dict into the PlayerData.quests_active dict.(quests_active is a dictionary of quests(also dictionaries) inside of the PlayerData dictionary lol) But i cant seem to get it to work. I've done it a couple different ways now, including the way the Godot documentation states on how to add Dinctionaries into dictionaries. Please help, this is the error I get from QuestHandler:
Invalid set index 'tutorialQuest' (on base: 'Nil') with value of type 'Dictionary'
QuestBase:
var storyQuests = {
"tutorialQuest":{
"name" : "Your First Steps",#Name of the Quest
"desc" : "Get to know your environment and learn the ropes.",#Description of the Quest
"level" : 1, #Required level before player can accept quest
"questType" : 0, #0=Story Quest || 1=Side Quest || 2=Repeateable Quest
"taskType": 0, #0=Progressive(task must be completed in order) || 1=Synchronous(tasks can be completed in any order, and all at once)
"tasks":{#Dictionary of Quest's Tasks
"task1":{
"text":"Talk to Bjorn",#Text to display in Quest log
"type":0,#0=Talk,1=Slay,2=Fetch,3=Deliver,4=Collect,5=Goto
"quantity":0,#Determines the amount to complete task for Slay, Fetch, and Collect
"target":"Bjorn",#Determines Who to talk to, or who to slay, or what to collect.
"completed":false#Is this task complete?
},
"task2":{
"text":"Talk to Bjorn",
"type":"Talk",
"target":"Bjorn",
"completed":false
},
"task3":{
"text":"Talk to Bjorn",
"type":"Talk",
"target":"Bjorn",
"completed":false
}
},
"itemReward":{
"items":["Sword", "Basic Elixer"],#Names of items to give
"amount":[1, 5]#Amount of each item to give, respectively.
},
"expReward":{
"skill":["Forestry","Smithing"],#Names of skills to add Exp to
"amount": [100,100] #Amount to add to each skill, respectively.
#1st number will increase first skill in "skill", etc...
},
"Complete":false,
"Failed":false
}
}
PlayerData:
var playerData = {
... irrelevant player data...
#Quests
"quests_active": {"blank":"blank"},
"quests_completed": {},
"quests_failed": {},
and Finally, Quest Handler:
func startQuest(questName: String):
var active_quests = PlayerData.playerData.get("quests_active")
if QuestBase.storyQuests.has(questName):
var questCopy = QuestBase.storyQuests.get(questName).duplicate(true)
PlayerData.playerData.get("quests_active")[questName] = questCopy #.quests_active.append(questCopy)
#print("Story Quest Started: " + PlayerData.playerData.QuestsActive.get(questName).get("name"))
elif QuestBase.sideQuests.has(questName):
var questCopy = QuestBase.sideQuests.get(questName).duplicate(true)
active_quests.append(questCopy)
#print("Side Quest Started: " + PlayerData.playerData.QuestsActive.get(questName).get("name"))
else:
print("Quest Doesn't Exist! Check Spelling!")

R Jsonlite - How to iterate a JSON list of objects?

I'm very new in R, but I was tasked with reading a JSON file that looks like the following :
{
"revisions" : [
{"number": 1, "description" : "first revision"},
{"number": 2, "description" : "second revision"},
{"number": 3, "description" : "third revision"}
]
}
I need to do some data manipulation iterating over revisions, but I can't understand what type of data structure jsonlite is transforming this list into, it seems it transposed it.
This is what I've tried :
json = fromJSON('data.json')
for (revision in json$revisions) {
print(revision$number) # Doesn't work
print(revision['number']) # Doesn't work
}
How can I read the json file in the way I'm trying above?
Using R 3.6.1, ideally I need to keep it to the base functions
json$revisions is a data.frame so you can try something like
for (i in seq(nrow(json$revisions))) {
print(json$revisions$number[i])
}

How to properly set Firebase Realtime Database to avoid null value at the beginning of array?

I'm new to NoSQL database. Currently I'm trying to use the Firebase and integrate it with iOS. When it comes to predefine the database, with trial and error, I try to make it look like this:
When I tried to retrieve the "stories" path in iOS, I get json structure like this:
[
<null>,
{
comments: [
<null>,
1,
2,
3
],
desc: "Blue versus red in a classic battle of good versus evil and right versus wrong.",
duration: 30,
rating: 4.42,
tags: [
<null>,
"fantasy",
"scifi"
title: "The Order of the Midnight Sun",
writer: 1
]
}
]
My question is, why there's always a null at the beginning of each array? What should I do in the database editor to avoid the null?
It looks like you start pushing data to index 1 and not 0, inserting/retrieving data to/from a list starts with index 0:

CouchDB View with 2 Keys

I am looking for a general solution to a problem with couchdb views.
For example, have a view result like this:
{"total_rows":4,"offset":0,"rows":[
{"id":"1","key":["imported","1"],"value":null},
{"id":"2","key":["imported","2"],"value":null},
{"id":"3","key":["imported","3"],"value":null},
{"id":"4","key":["mapped","4"],"value":null},
{"id":"5,"key":["mapped","5"],"value":null}
]
1) If I want to select only "imported" documents I would use this:
view?startkey=["imported"]&endkey=["imported",{}]
2) If I want to select all imported documents with an higher id then 2:
view?startkey=["imported",2]&endkey=["imported",{}]
3) If I want to select all imported documents with an id between 2 and 4:
view?startkey=["imported",2]&endkey=["imported",4]
My Questtion is: How can I select all Rows with an id between 2 and 4?
You can try to extend the solution above, but prepend keys with a kind of "emit index" flag like this:
map: function (doc) {
emit ([0, doc.number, doc.category]); // direct order
emit ([1, doc.category, doc.number]); // reverse order
}
so you will be able to request them with
view?startkey=[0, 2]&endkey=[0, 4, {}]
or
view?startkey=[1, 'imported', 2]&endkey=[1, 'imported', 4]
But 2 different views will be better anyway.
I ran into the same problem a little while ago so I'll explain my solution. Inside of any map function you can have multiple emit() calls. A map function in your case might look like:
function(doc) {
emit([doc.number, doc.category], null);
emit([doc.category, doc.number], null);
}
You can also use ?include_docs=true to get the documents back from any of your queries. Then your query to get back rows 2 to 4 would be
view?startkey=[2]&endkey=[4,{}]
You can view the rules for sorting at CouchDB View Collation

Need to generate an json array, then loop through the values

I need to create some sort of a state for a bunch of elements on a page.
The stats can be 1 or -1.
Now on the server side I will generate a JSON array and put it in my .aspx page like this:
var someArray = { 100:-1, 1001:1, 102:1, 103:-1 }
How do I loop through each value now in javascript?
BTW, is my JSON array format correct?
Note that someArray is a misnomer as it is actually an Object. To loop through it, though:
for(key in someArray) {
alert(someArray[key]);
}
As far as whether it is valid, the above works for me but I believe technically keys should be strings:
{
"100": -1,
"1001": 1,
"102": 1,
"103": -1
}
Check out this handy JSON validator.

Resources