I have a YAML file like:
top:
names:
- name: john1
- name: john2
- name: john3
- name: john.doe
Now I have to remove top/names/name(john.doe). How can I achieve that with yaml-cpp? My code is:
void deleteNode(string id)
{
YAML::Node config = YAML::LoadFile("doc.yaml");
for (int i = 0; i < config["top"]["names"].size(); i++)
{
if(config["top"]["names"][i]["name"].as<string>() == id)
{
config["top"]["names"].remove(config["top"]["names"][i]);
break;
}
}
}
deleteNode("john.doe");
This doesn't seem to do anything.
Since you're dealing with a sequence, you have to remove a node by its index:
void deleteNode(string id) {
YAML::Node config = YAML::LoadFile("doc.yaml");
YAML::Node names = config["top"]["names"];
for (int i = 0; i < names.size(); i++) {
if(names[i]["name"].as<string>() == id) {
names.remove(i);
break;
}
}
}
Removing a node from a sequence is fixed in libyaml-cpp version 0.6.3. You should update to that version or above if your version is older than that.
Related
We're wondering if it possible to flat YAML config object? For example, our config files looks like
vertx:
verticle:
instance: 1
metrics:
options:
enabled: true
And we would like to access to our config values with only one operation, for example:
config.getInteger("vertx.verticle.instance")
instead of having to do:
config.getJsonObject("vertx").getJsonObject("verticle").getInteger("integer")
Thanks.
Vert.x supports Json Pointers from RFC6901. You could do:
JsonPointer pointer = JsonPointer.from("/vertx/verticle/instance");
Integer instance = (Integer) pointer.queryJson(config);
While the API doesn't support it directly, it seems easy enough to implement yourself:
public class FlatConfig {
private final JsonObject root;
public FlatConfig(JsonObject root) {
this.root = root;
}
private JsonObject walk(String[] path) {
JsonObject cur = root;
// skip last element since it contains the value
for (int i = 0; i < path.length - 2; i++) {
cur = cur.getJsonObject(path[i]);
}
return cur;
}
public Integer getInteger(String path) {
final String[] splitPath = path.split(".");
return walk(splitPath).getInteger(splitPath[splitPath.length - 1]);
}
}
You can add other methods for retrieving other types as necessary.
Currently, the code below checks the if the data meets two criteria and then it's pushed into an array, but the need now is to get the latest data that meet those criteria.
The date's index within the dataset is [19] (20th column).
How would I go about tweaking it?
for (var i = 0; i < values.length; i++) {
if (values[i][0] == productCode && values[i][2] == productVersao) {
data.push(values[i]);
}
}
Thanks a lot in advance!
function themostrecent(values) {
values.sort(function(a,b){
var A=new Date(a[19]).valueOf();
var B=new Date(b[19]).valueOf();
return B-A;
});
for (var i = 0; i < values.length; i++) {
if (values[i][0] == productCode && values[i][2] == productVersao) {
data.push(values[i]);
break;
}
}
return data;
}
I have small issue with managing the downloading data of firebase to my ionic application.
For example: In the normal case [such as below code], the downloading data is normal [such as this image]
constructor(...){
this.questionsList = this.afd.list('/questions/');
}
But if I used "setInterval" [such as below code], the downloading of data increase [such as this image]
constructor(...){
this.questionsList = this.afd.list('/questions/');
this.favoritesList = this.afd.list('/favorites/',{
query:{
orderByChild:'user_id',
equalTo: userService.id,
}
})
this.joinObjects();
this.refreshIntervalId=setInterval(()=>{
this.joinObjects();
},250);
}
joinObjects(){
let TempListX=[];
this.favoritesList.take(1).subscribe(data1=>{
this.questionsList.take(1).subscribe(data2=>{
TempListX = data1.slice(0);
for(let i=0; i<data1.length; i++){
for(let j=0; j<data2.length; j++){
if(data1[i].question_id==data2[j].$key){
TempListX[i].qTitle=data2[j].title;
}
}
}
if (JSON.stringify(TempListX)===JSON.stringify(this.TempFavoritesList)) {
}else{
this.TempFavoritesList=TempListX.slice();
}
})
})
}
So is there any way to make the downloading data be such as normal case ?
As requested here is a refactored version of your code. I have to say I did not test it but it should outline the concept. The method joinObjects() is called every time an updated value/list arrives and not in a fixed interval which creates a lot of overhead. Notice the new instance variables I added and that I renamed your observables to favoritesList$ and questionsList$ (the dollar suffix is good practice to indicate that it is an observable (not a subscription, value, ...).
public questions;
public favorites;
constructor(...) {
this.questionsList$ = this.afd.list('/questions/');
this.favoritesList$ = this.afd.list('/favorites/', {
query: {
orderByChild: 'user_id',
equalTo: userService.id,
},
});
this.questionsList$.subscribe(updatedList => {
this.questions = updatedList;
this.joinObjects();
});
this.favoritesList$.subscribe(updatedList => {
this.favorites = updatedList;
this.joinObjects();
});
}
joinObjects() {
let TempListX = [];
TempListX = this.questions.slice(0);
for (let i = 0; i < this.questions.length; i++) {
for (let j = 0; j < this.favorites.length; j++) {
if (this.questions[i].question_id == this.favorites[j].$key) {
TempListX[i].qTitle = this.favorites[j].title;
}
}
}
if (JSON.stringify(TempListX) === JSON.stringify(this.TempFavoritesList)) {
} else {
this.TempFavoritesList = TempListX.slice();
}
}
I hope this brings you closer to your goal!
I have implemented bubble sort in order to sort the IntDoublePair. For instance:
[1 0.5]
[1 0.8]
[1 0.67]
sorted as:
[1 0.5]
[1 0.67]
[1 0.8]
When I executed the code, it gave me the data not in sorted order. I am confused that where am I going wrong. I need some assistance.
private ArrayList<IntDoubleTextPair> sortCollection(ArrayList<IntDoubleTextPair> collection)
{
for (int current = 0; current < collection.size(); current++)
{
for (int next = 1; next < collection.size(); next++)
{
if (collection.get(current).getFirst().get() >= collection.get(next).getFirst().get())
{
if (collection.get(current).getSecond().get() > collection.get(next).getSecond().get())
{
temp = collection.get(next);
collection.set(next, collection.get(current));
collection.set(current, temp);
}
}
}
}
return collection;
}
I think you may have some faulty logic:
if (collection.get(current).getFirst().get() >= collection.get(next).getFirst().get())
{
if (collection.get(current).getSecond().get() > collection.get(next).getSecond().get())
{
temp = collection.get(next);
collection.set(next, collection.get(current));
collection.set(current, temp);
}
}
with those two nested if statements, the switch won't happen in this example, but it needs to:
[2 .1]
[1 .9]
because even though the first if statement evaluates true, the second if statement fails because it only looks at the second number. Perhaps this would work better:
if (collection.get(current).getFirst().get() >= collection.get(next).getFirst().get())
{
if (collection.get(current).getFirst().get() == collection.get(next).getFirst().get())
{
if (collection.get(current).getSecond().get() > collection.get(next).getSecond().get())
{
temp = collection.get(next);
collection.set(next, collection.get(current));
collection.set(current, temp);
}
}
else
{
temp = collection.get(next);
collection.set(next, collection.get(current));
collection.set(current, temp);
}
}
Happy coding! Leave a comment if you have any questions.
I think the sort should work at least for the array that you are passing (although there is a problem in nested if conditions), but there might be an issue when you pass reference to temp in swap operation so try creating a temp object and instead of passing reference pass the values :
private ArrayList<IntDoubleTextPair> sortCollection(ArrayList<IntDoubleTextPair> collection)
{
for (int current = 0; current < collection.size(); current++)
{
for (int next = 1; next < collection.size(); next++)
{
if (collection.get(current).getFirst().get() >= collection.get(next).getFirst().get())
{
if (collection.get(current).getSecond().get() > collection.get(next).getSecond().get())
{
IntDoubleTextPair temp= new IntDoubleTextPair();
temp.getFirst() = collection.get(next).getFirst();
temp.getSecond() = collection.get(next).getSecond();
collection.set(next, collection.get(current));
collection.set(current, temp);
}
else if(collection.get(current).getFirst().get() != collection.get(next).getFirst().get()){
IntDoubleTextPair temp= new IntDoubleTextPair();
temp.getFirst() = collection.get(next).getFirst();
temp.getSecond() = collection.get(next).getSecond();
collection.set(next, collection.get(current));
collection.set(current, temp);
}
}
}
}
return collection;
}
I was wondering if anyone can recommend a tool to analyze zipped or any archive file. I do not mean checking what is inside the archive but more about how it was compressed, with what compression method, etc.
Thanks!
For data compressed into a ZIP file, the command-line tool zipinfo is quite helpful, particularly when using the '-v' argument (for verbose mode). I learned of zipinfo from this zip-related question on SuperUser
I recently ran into an issue where the zip's being created by one tool would only open with certain programs and not others. The issue turned out to be that directories didn't have entries in the zip file, they were just implied by the presence of files in them. Also all the directory separators were backslashes instead of forward slashes.
zipinfo didn't really help with these bits. I needed to see the zip entries so I ended up writing this the following which allowed me diff the directory entries with a known good version
using System;
using System.IO;
using System.Text;
namespace ZipAnalysis
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("No filename specified");
Console.WriteLine("Press any key to exit");
Console.ReadKey(true);
return;
}
string fileName = args[0];
if (!File.Exists(fileName))
{
Console.WriteLine($"File not found: {fileName}");
Console.WriteLine("Press any key to exit");
Console.ReadKey(true);
return;
}
using (var file = File.OpenRead(fileName))
{
//First, find the End of central directory record
BinaryReader reader = new BinaryReader(file);
int entryCount = ReadEndOfCentralDirectory(reader);
if (entryCount > 0)
{
ReadCentralDirectory(reader, entryCount);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey(true);
}
private static int ReadEndOfCentralDirectory(BinaryReader reader)
{
var b = reader.ReadByte();
int result = 0;
long fileSize = reader.BaseStream.Length;
while (result == 0 && reader.BaseStream.Position < fileSize)
{
while (b != 0x50)
{
if (reader.BaseStream.Position < fileSize)
b = reader.ReadByte();
else
break;
}
if (reader.BaseStream.Position >= fileSize)
{
break;
}
if (reader.ReadByte() == 0x4b && reader.ReadByte() == 0x05 && reader.ReadByte() == 0x06)
{
int diskNumber = reader.ReadInt16();
int centralDirectoryStartDiskNumber = reader.ReadInt16();
int centralDirectoryCount = reader.ReadInt16();
int centralDirectoryTotal = reader.ReadInt16();
result = centralDirectoryTotal;
int centralDirectorySize = reader.ReadInt32();
int centralDirectoryOffset = reader.ReadInt32();
int commentLength = reader.ReadInt16();
string comment = Encoding.ASCII.GetString(reader.ReadBytes(commentLength));
Console.WriteLine("EOCD Found");
Console.WriteLine($"Disk Number: {diskNumber}");
Console.WriteLine($"Central Directory Disk Number: {centralDirectoryStartDiskNumber}");
Console.WriteLine($"Central Directory Count: {centralDirectoryCount}");
Console.WriteLine($"Central Directory Total: {centralDirectoryTotal}");
Console.WriteLine($"Central Directory Size: {centralDirectorySize}");
Console.WriteLine($"Central Directory Offset: {centralDirectoryOffset}");
Console.WriteLine($"Comment: {comment}");
reader.BaseStream.Seek(centralDirectoryOffset, SeekOrigin.Begin);
}
b=0;
}
return result;
}
private static void ReadCentralDirectory(BinaryReader reader, int count)
{
for (int i = 0; i < count; i++)
{
var signature = reader.ReadInt32();
if (signature == 0x02014b50)
{
Console.WriteLine($"Version Made By: {reader.ReadInt16()}");
Console.WriteLine($"Minimum version to extract: {reader.ReadInt16()}");
Console.WriteLine($"Bit Flag: {reader.ReadInt16()}");
Console.WriteLine($"Compression Method: {reader.ReadInt16()}");
Console.WriteLine($"File Last Modification Time: {reader.ReadInt16()}");
Console.WriteLine($"File Last Modification Date: {reader.ReadInt16()}");
Console.WriteLine($"CRC: {reader.ReadInt32()}");
Console.WriteLine($"CompressedSize: {reader.ReadInt32()}");
Console.WriteLine($"UncompressedSize: {reader.ReadInt32()}");
var fileNameLength = reader.ReadInt16();
var extraFieldLength = reader.ReadInt16();
var fileCommentLength = reader.ReadInt16();
Console.WriteLine($"Disk number where file starts: {reader.ReadInt16()}");
Console.WriteLine($"Internal file attributes: {reader.ReadInt16()}");
Console.WriteLine($"External file attributes: {reader.ReadInt32()}");
Console.WriteLine($"Relative offset of local file header: {reader.ReadInt32()}");
string filename = Encoding.ASCII.GetString(reader.ReadBytes(fileNameLength));
string extraField = Encoding.ASCII.GetString(reader.ReadBytes(extraFieldLength));
string fileComment = Encoding.ASCII.GetString(reader.ReadBytes(fileCommentLength));
Console.WriteLine($"Filename: {filename}");
Console.WriteLine($"Extra Field: {extraField}");
Console.WriteLine($"File Comment: {fileComment}");
}
}
}
}
}