How to append comments next to each line in a json string? - javascript

I want to create a markdown file which includes a js object.
I want to add commentaries which are stored in an other object to each line.
The output should look like this:
{
"a": "test, //commentary1
"b": "test2" //commentary2
}
My first intention was to rewrite the stringify function, but it's a bit tricky for edge cases.
How can I achieve this functionality in more better way?

You can opt for 2 options
Add comment as keys like
{
"_comment": "comment text goes here..."
}
Instead of json object use json array and parse accordingly
{
"a": ["test", "commentary1"],
"b": ["test2", "commentary2"]
}

Related

Converting a string to a list and seperate each element

So I have a use case in which I enter indexes and descriptions which belong to a round. I created a JS function that allows me to enter these indexes and descriptions. When I strip the data from the post request I get the following data:
['0,This is a testround', '1,This is a new testround']
I want to split this data so that I can seperate the 0 in an index variable and the following description "This is a testround" in a description variable. Please note that the description can only contain comma's. The indexes are not always corresponding with the indexes of an array: [[0,"Description1"],[5,"Description2"]] could happen
A possible solution could be to split the string on a comma and use str[0] for the index and the other parts for the description but to me this would look like an ugly solution.
What should I do?
I use the following JS to save the rounds to a playerdata div from which i extract the list above (in which items is the list with the index and description)
function item_checkbox(items,n) {
return `
<input type="checkbox" style="display:none;" name="${itemList[n]}" value="${items}" checked>
`
}
function add_to_itemData(items, n) {
itemDataEl = document.getElementById(itemData[n])
itemDataEl.innerHTML = itemDataEl.innerHTML + item_checkbox(items, n)
}
Thanks for any help in advance
While you say that it would be an "ugly" solution to solve it by splitting, I think it's a pretty straightforward routine, given the format the data is returned to you.
['0,This is a testround', '1,This is a new testround'].map(v => v.split(','));
... would translate correctly to:
[
[ "0", "This is a testround" ],
[ "1", "This is a new testround" ]
]
But I guess I get what you mean. There are a few possible problems - for example, that of key uniqueness. You could solve this one by keeping each row into Javascript objects instead of arrays, and you can convert it quite easily by using Object.fromEntries(), since it conveniently accepts each row of bidimensional arrays as key/value pairs:
Object.fromEntries([
[ "0", "This is a testround" ],
[ "1", "This is a new testround" ],
[ "1", "This is a dupe testround" ] // this will overwrite the previous entry
]);
// {0: "This is a testround", 1: "This is a dupe testround"}
You might want to take a few extra steps for additional control, like using .trim() to remove leading or trailing whitespaces or testing/filtering/splitting them using a custom regex.

How to access an attribute from a JSON line saved in a position from an array?

This may be a very simple question but I really can't seem to make it work.
I have several JSON lines and a notes array.
Using notes.push(JSONline) I am saving one JSON line per array position, I assume, so in the following manner:
//notes[1]
{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":51}
//notes[2]
{"id":"27","valuee":"134","datee":"2016-04-05T15:15:47.238+0100","id2":53}
//notes[3]
{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":52}
Here is my problem: I want to print one specific attribute, for example id from one specific JSON line in the array. How can I do this?
When I do console.log(notes) it prints all the JSON lines just as expected. But if I do console.log(notes[1]) it prints the first character of the JSON line in that position, not the whole line.
Similarly console.log(notes[1].id) does not print the id from the first JSON line, in fact it prints 'undefined'.
What am I doing wrong?
Thank you so much.
I'd recommend that you parse all the json when you are pushing to notes, like:
notes.push(JSON.parse(JSONLine))
If you are somehow attached to having json strings in an array instead of objects, which I wouldn't recommend, you could always just parse once you have the jsonLine id
JSON.parse(notes[id]).id
Basically, you want to use JSON.parse for either solution and I'd strongly recommend converting them to objects once at the beginning.
You need to remember that JSON is the string representation of a JS object. JS strings have similar index accessor methods to arrays which is why you can write console.log(notes[0]) and get back the first letter.
JavaScript doesn't allow you to access the string using object notation, however, so console.log(notes[0].id) will not work and the reason you get undefined.
To access the data in the string using this method you need to parse the string to an object first.
var notes = ['{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":51}'];
var note0 = JSON.parse(notes[0]);
var id = note0.id;
DEMO
This leaves the question of why you have an array of JSON strings. While it's not weird or unusual, it might not be the most optimum solution. Instead you could build an array of objects and then stringify the whole data structure to keep it manageable.
var obj0 = {
"id": "26",
"valuee": "20",
"datee": "2016-04-05T15:15:45.184+0100",
id2: 51
};
var obj1 = {
"id": "27",
"valuee": "134",
"datee": "2016-04-05T15:15:47.238+0100",
"id2": 53
}
var arr = [obj0, obj1];
var json = JSON.stringify(arr);
OUTPUT
[
{
"id": "26",
"valuee": "20",
"datee": "2016-04-05T15:15:45.184+0100",
"id2": 51
},
{
"id": "27",
"valuee": "134",
"datee": "2016-04-05T15:15:47.238+0100",
"id2": 53
}
]
You can then parse the JSON back to an array and access it like before:
var notes = JSON.parse(json);
notes[0].id // 26
That's because you have {"id": "value"... as a string in your key value pairs. "id" is a string so you can't reference it like a property. 1. use
var notes = JSON.parse(notes);
as mentioned in the comments by The alpha
or remove the quotes try
{id:"26", ...}
that's why notes[i].id is returning undefined

How to keep order from json.parse? [duplicate]

I have some data which I originally stored in a generic Javascript object, with the ID as a key:
{
"7": {"id":"7","name":"Hello"},
"3": {"id":"3","name":"World"},
...
}
However, I discovered that browsers do not guarantee a particular object order when looping through them, so in the above "3" would come before "7". I switched to using an array format like this:
[
{"id":"7","name":"Hello"},
{"id":"3","name":"World"},
...
]
Now, I can loop in the correct order but cannot do fast lookups, e.g. data["3"] without having to loop through the array.
Is there a good way to combine both approaches? I would rather avoid using a separate object for each format, because the object is pretty large (hundreds of elements).
I have run across this problem as well. A solution is to keep an ordered array of keys in addition to the original object.
var objects = {
"7": {"id":"7","name":"Hello"},
"3": {"id":"3","name":"World"},
...
}
var order = [ "3", "7", ... ];
Now if you want the second element you can do this lookup:
var second_object = objects[order[1]];
The ECMA standard does not say anything about the order of the elements in an object. And specifically Chrome reorders the keys when they look like numbers.
Example:
var example = {
"a": "a",
"b": "b",
"1": "1",
"2": "2"
};
if you print this in Chrome will get something like:
{
1: "1",
2: "2",
"a": "a",
"b": "b"
};
It's a little sour .. but life.
You could use the solution Andy linked as well, basically wrapping these two together in one object.
An alternative that I use a lot is a custom map function that allows you to specify the order in which the object is traversed. Typically you will do sorting when you're printing your data to the user so while you loop and create your table rows (for instance) your iterator will pass the rows in the order your sort function specifies. I thought it was a nice idea :)
The signature looks like:
function map(object, callback, sort_function);
Example usage:
map(object, function (row) {
table.add_row(row.header, row.value);
}, function (key1, key2) {
return object[key1] - object[key2];
});
Rather than coding your own, there are off-the-shelf libraries available to provide "as provided" JSON parsing or "consistently sorted" JSON printing for display.
You might well consider either of these:
The 'json-order' package offers parsing, formatting & pretty-printing with stable ordering. This is based on having ordered input.
The 'fast-json-stable-stringify' package offers deterministic formatting based on sorting.

JavaScript object data extraction (JSON Stringify/Parse or without?)

I am trying to figure out if I JSON.Stringify an object like this:
{"m_id":"xxx","record":
{"USER":"yyy","PWD","zzz","_createdAt":
11111."_updatedAt":00000},"state":"valid"}
and then try to JSON.Parse out only the USER and PWD, not have to just call the object, but go through stringify. how would that work?
thanks.
I'm not sure why you're talking about stringifying your object. You'd stringify it if you needed to send the data across a network or something, not when you need to manipulate it in JS.
...how do I extract the strings in {...USER: "aaa", PWD: "zzz"...}?
Assuming you have a variable referring to the object, something like the following (with or without nice line breaks and indenting to make it readable, and with or without quotes around the property names):
var obj = {
"m_id": "xxx",
"record": {
"USER": "yyy",
"PWD" : "zzz",
"_createdAt": 11111,
"_updatedAt": 00000
},
"state": "valid"
};
Then you can access the properties in the nested record object as follows:
console.log( obj.record.USER ); // outputs "yyy"
console.log( obj.record.PWD ); // outputs "zzz"
// etc.
(Note: in your question you had two typos, a comma that should've been a colon in between "PWD" and "zzz", and a dot that should've been a comma in between 11111 and "_updatedAt". There's no way that JSON.stringify() would have produced the string that you showed with those mistakes.)
If you want the strings "USER", "PWD" etc as an array, then use Object.keys.
If you want to iterate them, just use a normal for-in enumeration.
I might have misunderstood the question, but if I think it is what it is then try using
var tmp = JSON.parse(string_to_convert)
this should suffice to convert your string to a proper Javascript Object
Then you can do
for(var index in tmp){
console.log(tmp[index]);
}
and this should list all the keys on the first set of properties. If you want to do a nested thing, then use recursion on the properties. Hope this makes sense...

How to keep an Javascript object/array ordered while also maintaining key lookups?

I have some data which I originally stored in a generic Javascript object, with the ID as a key:
{
"7": {"id":"7","name":"Hello"},
"3": {"id":"3","name":"World"},
...
}
However, I discovered that browsers do not guarantee a particular object order when looping through them, so in the above "3" would come before "7". I switched to using an array format like this:
[
{"id":"7","name":"Hello"},
{"id":"3","name":"World"},
...
]
Now, I can loop in the correct order but cannot do fast lookups, e.g. data["3"] without having to loop through the array.
Is there a good way to combine both approaches? I would rather avoid using a separate object for each format, because the object is pretty large (hundreds of elements).
I have run across this problem as well. A solution is to keep an ordered array of keys in addition to the original object.
var objects = {
"7": {"id":"7","name":"Hello"},
"3": {"id":"3","name":"World"},
...
}
var order = [ "3", "7", ... ];
Now if you want the second element you can do this lookup:
var second_object = objects[order[1]];
The ECMA standard does not say anything about the order of the elements in an object. And specifically Chrome reorders the keys when they look like numbers.
Example:
var example = {
"a": "a",
"b": "b",
"1": "1",
"2": "2"
};
if you print this in Chrome will get something like:
{
1: "1",
2: "2",
"a": "a",
"b": "b"
};
It's a little sour .. but life.
You could use the solution Andy linked as well, basically wrapping these two together in one object.
An alternative that I use a lot is a custom map function that allows you to specify the order in which the object is traversed. Typically you will do sorting when you're printing your data to the user so while you loop and create your table rows (for instance) your iterator will pass the rows in the order your sort function specifies. I thought it was a nice idea :)
The signature looks like:
function map(object, callback, sort_function);
Example usage:
map(object, function (row) {
table.add_row(row.header, row.value);
}, function (key1, key2) {
return object[key1] - object[key2];
});
Rather than coding your own, there are off-the-shelf libraries available to provide "as provided" JSON parsing or "consistently sorted" JSON printing for display.
You might well consider either of these:
The 'json-order' package offers parsing, formatting & pretty-printing with stable ordering. This is based on having ordered input.
The 'fast-json-stable-stringify' package offers deterministic formatting based on sorting.

Categories

Resources