I am making a tokenizer that builds an abstract tree and I want to collect all the "text" from an array that is output by my tokenizer.
Output:
{
"error": false,
"tokens": [
{
"type": "keyword",
"value": "print",
"text": "print"
},
{
"type": "string",
"value": "hello world",
"text": "hello world"
},
{
"type": "keyword",
"value": "var",
"text": "var"
},
{
"type": "keyword_valueof",
"value": "msg",
"text": "msg"
},
{
"type": "operator",
"value": "eq",
"text": "="
},
{
"type": "string",
"value": "secret message",
"text": "secret message"
}...
It should turn out like this:
print "hello world"
var msg = "secret message"
Can you help me, I don't know how to do this.
If you want to extract each value of the "text" to an array, you can use the map() method:
const arr = obj.tokens.map((token) => token.text);
Where 'obj' is the main object (with the "errors" and "tokens" keys).
To print each element of the array in a new line:
arr.forEach(elem => {console.log(elem);});
e.g.:
const obj = {
"error": false,
"tokens": [
{
"type": "...",
"value": "...",
"text": "text 1"
},
{
"type": "...",
"value": "...",
"text": "text 2"
}
]
}
const tokensArr = obj.tokens.map(token => token.text);
tokensArr.forEach(elem => {console.log(elem);});
Is this what you're looking for?
let array = ["secretMessage", "anotherMessage"]; //The array
let theNumberIdOfMessage = 0; //The first item of the array
console.log(array[theNumberIdOfMessage]); //Get the item first in the array and log it
theNumberIdOfMessage = 1; //The second item of the array
console.log(array[theNumberIdOfMessage]); //Log the second item
Related
I have a JSON like so:
{
"parent": {
"type": "Object",
"value": {
"childName": { "type": "String", "value": "A string" }
}
}
}
Pretty much, the pattern is parent has type and value, but I want the value of parent to be value
{
"parent": {
"childName": "A string"
}
}
How can I set the parent's value to be the child named value recursively in JavaScript?
The main issue I am having is doing this recursively for a very large file.
Examples:
The start value of Level is `{ "type": "string", "value": "A string" }
I want to make the value of Level become "A String", making the end value of Level become "A String"
The start value of parentObject is { "type": "Object", "value": { "anotherObject": { "type": "string", "value": "Another string" }, "secondObject": { "type": "string", "value": "second string" } } }
I want to make the value of parentObject become { "anotherObject": { "type": "string", "value": "Another string" }, "secondObject": { "type": "string", "value": "second string" } }
And the value of anotherObject become "Another string"
Making the final result
{"parentObject": { "anotherObject": "Another string" }, { "secondObject": "second string" }}
Here is a example JSON file
The first thing is the object should be symmetric if your want to do it in a recursive way.
Example:
const input = {
"parentObject": {
"type": "Object",
"value": {
"anotherObject": {
"type": "string",
"value": "Another string"
}
}
}
};
The recursive function is something like this.
const input = {
"parentObject": {
"type": "Object",
"value": {
"anotherObject1": {
"type": "string",
"value": "Another string"
},
"anotherObject2": {
"type": "string",
"value": "Another string"
}
}
}
};
const recursivefn = (obj) => {
const keys = Object.keys(obj);
let acc = {}
keys.forEach((key)=>{
if (typeof obj[key].value === 'object') {
acc = { ...acc, [key]: recursivefn(obj[key].value) };
} else {
acc = { ...acc, [key]: obj[key].value};
}
});
return acc;
}
console.log(recursivefn(input));
I am trying to define a "complex" object:
var tM = JSON.parse('{"version":"","series":[{"name":"","possModes":[],"instance":[{"date":"","mode":""}]}]}');
where all items of array "instance" should be objects of type
{"date":"","mode":""}
and all items of array "series" should be objects of type
{"name":"","possModes":[],"instance":[{"date":"","mode":""}]}
The problem is that only the items of index [0] are getting the proper properties and items of higher indexes are "undefined", so I cannot set them to their needed values.
I have also tried to define tM explicitly, like:
var Cinstance = new Object();
Cinstance.date = "";
Cinstance.mode = "";
var Cseries = new Object();
Cseries.name = '';
Cseries.possModes = [];
Cseries.instance = [new Object(Cinstance)];
var tM= new Object();
tM.version = "";
tM.series = [new Object(Cseries)];
and also like:
var tM = {series:
[{instance:
[{date:"",mode:""}
]
}
]
}
(this is a version reduced to my specific problem).
Of course, they both end up with the same result - only items of index [0] are defined.
The data structure provided by the OP ...
{
"version": "",
"series": [{
"name": "",
"possModes": [],
"instance": [{
"date": "",
"mode": ""
}]
}]
}
... does validate against the following JSON schema ...
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "My-Special-Schema-Or-Data-Structure-Title",
"description": "Whatever I have to say about my described structure",
"type": "object",
"properties": {
"version": {
"description": " ... ",
"type": "string"
},
"series": {
"description": " ... ",
"type": "array",
"minItems": 1,
"items": {
"description": " ... ",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"possModes": {
"description": " ... ",
"type": "array"
},
"instance": {
"description": " ... ",
"type": "array",
"minItems": 1,
"items": {
"description": " ... ",
"type": "object",
"properties": {
"date": {
"type": "string"
},
"mode": {
"type": "string"
}
},
"required": [
"date",
"mode"
]
}
}
},
"required": [
"name",
"possModes",
"instance"
]
}
}
},
"required": [
"version",
"series"
]
}
There is even a JSON Schema Generator one could start with. Passing the OP's originally provided data structure, one gets a solid base of a JSON Schema, one then can continue tailoring.
{
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"column_0": {
"value": "1",
"label": "name"
},
"condition_0": {
"value": "101",
"label": "Is equal to"
},
"column_1": {
"value": "2",
"label": "age"
},
"condition_1": {
"value": "102",
"label": "Is less than"
}
}
I have the above object in JavaScript. From this object I need to create the following object. Need to find a way which is good from performance point of view. The below conditions array is based on the object starting with 'column_' in the above object.
For example: if there are column_0, column_1, column_2, the length of conditions array will be 3. These columns will be coming dynamically, can be from 0-n, n = any integer >= 0. (i.e. column_0 - column_n)
The same condition applies for condition_0, condition_1. Also, condition_0 is always associated with column_0, condition_1 is always associated with column_1 ans so on.
{
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"conditions" : [
{
"column_id": 1, // column_0.value
"column_name": "name", // column_0.label
"condition_id": 101 // condition_0.value
},
{
"column_id": 2, // column_1.value
"column_name": "age", // column_1.label
"condition_id": 102 // condition_1.value
}
],
}
extract the conditions using ...rest, reduce the Object.entries , construct the data structure and push it to the resulting array, finally put everything back together :
const data = {
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"column_0": {
"value": "1",
"label": "name"
},
"condition_0": {
"value": "101",
"label": "Is equal to"
},
"column_1": {
"value": "2",
"label": "age"
},
"condition_1": {
"value": "102",
"label": "Is less than"
}
}
const {
name,
description,
data_table_id,
...rest
} = data;
const conditions = Object.entries(rest).reduce((all, [key, obj]) => {
if (key.startsWith('condition')) {
const id = key.split('_')[1];
const condition = {
"column_id": rest[`column_${id}`].value,
"column_name": rest[`column_${id}`].label,
"condition_id": obj.value,
}
all.push(condition)
}
return all;
}, []);
const result = {
name,
description,
data_table_id,
conditions
}
console.log(result)
So I have a bunch of JSON data and it contains a few fields. for example:
[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
what I'm trying to do is kind of conversion table (from a different JSON file)
if a field has the value 'a' replace it with 'some other text..' etc.
I have a service for the JSON pipeline, so I guess this is the right place to do the replacement.
so for this example, I have the JSON above and in my conversion table I have the following terms:
next: forward,
song: music,
a: option1,
just: from
etc...
What you are looking for can be achieved with templates. Replace the variable sections with some specific markers that you can find and replace from some external tools such as perl or sed.
For example, you could have a template.json with something like this:
...
"type": {
"value": "##VALUE##"
}
...
Then when you need the actual JSON, you could pass this though an intermediate script that replaces these templates with actual data.
cat template.json | sed -e 's/##VALUE##/my_value/' > target.json
Alternatively, with Perl:
cat template.json | perl -pi -e 's:\#\#VALUE\#\#:my_value:' > target.json
The best way is to parse it, replace the text in the object, and then stringify it.
The next best way is to use a regular expression.
In this example, I catch exceptions if path cannot be indexed, and use ['type'] instead of .type so it will scale to indexing 'non-type' if you wish.
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const o = JSON.parse(data)
o[0].body.forEach(b => {
try {
if (b.extended.spl['type'].value === 'a') {
b.extended.spl['type'].value = 'CHANGED'
}
} catch (e) {}
})
const newData = JSON.stringify(o, null, 2)
console.log(newData)
A string replace approach will work if you know and can rely on your source conforming, such as the only "value" is inside "type"
const data = `[{
"id": "XXX",
"version": 1,
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"body": [{
"id": "XXX1",
"info": "three little birds",
"extended": {
"spl": {
"text": "song",
"type": {
"value": "a"
}
}
}
},
{
"id": "XXX2",
"info": [
"how are you?"
],
"extended": {
"spl": {
"text": "just",
"non-type": {
"value": "abc"
}
}
}
}
]
}]
`
const newData = data.replace(/"value": "a"/g, '"value": "NEWVALUE"')
console.log(newData)
I have this JSON object:
"Master": {
"nodeType": "Test",
"label": "Master",
"nodes": {
"event": {
"nodeType": "Test",
"label": "Test",
"itemTemplate": {
"label": "Test",
"properties": {
"icon": {
"label": "Test",
"description": "Test",
"valueType": "STRING",
"value": ""
}
}
},
"items": [
{
"icon": "test 2",
},
{
"icon": "test 1",
}
]
}
}
I want to access the items section. I've tried the following:
var obj = jQuery.parseJSON(json_object); //json object
alert(obj.nodes.items[0].icon); //Uncaught TypeError: Cannot read property 'items' of undefined
var items;
items = obj.Master.nodes.event.items;
alert(items[0].icon);
items result in an array
note your json is incorrect as is missing a leading { and two trailing }
json_object = '{ "Master": {
//
//
//
} }';
If not correct jQuery.parseJSON will fail.
Your JSON defines a single key called "Master". Try:
alert(obj.Master.nodes.items[0].icon);
console.log(obj.Master.nodes.event.items[0].icon)
check structure of your json here : http://jsonviewer.stack.hu/
that will help you to understand node inheritance
alert(obj.Master.nodes.event.items[0].icon);
and validate your json
http://jsonlint.com/