How to parse nested json-array in streaming fashion with zio-json - json

For a json array like this:
[
my-json-obj1,
my-json-obj2,
my-json-obj3,
....
my-json-objN
]
And MyJsonObj class that represents a mapping of single object in array I can say:
val myJson = '''[...]'''
ZStream
.fromIterable(myJson.toSeq)
.via(JsonDecoder[MyJsonObj].decodeJsonPipeline(JsonStreamDelimiter.Array))
to parse that array in a "streaming" way, i.e. emit mapped objects as they are parsed form the input as opposed to reading all the input first and then extracting the objects.
How can I do the same if the array is nested inside a json object say like this?:
{
"hugeArray":
[
my-json-obj1,
my-json-obj2,
my-json-obj3,
....
my-json-objN
]
}
I trawled through zio-json source code, but I can't find any foothole there for this use case. I guess I could carve out that array from the json document and feed that to decodeJsonPipeline. Is there any better, json-syntax aware way of doing this? If not directly in zio-json perhaps with help of some other open source json libraries?

Related

How do I parse JSON in Go where array elements have more than one type?

How can I parse a JSON response from https://api.twitchinsights.net/v1/bots/online to an array in Go and iterate over every entry?
I dont understand the struct because there are no keys only values...
Can anyone please help and explain how this works?
I've mapped it but then I get something like
map[_total:216 bots:[[anotherttvviewer 67063 1.632071051e+09] [defb 26097 1.632071051e+09] [commanderroot 17531 1.632071048e+09] [apparentlyher 16774 1.63207105e+09]...
But I cant iterate over the map.
Because the API you're working with returns data where it could be a string or a number (in the array of arrays property bots), you'll need to use []interface{} as the type for each element of that array because the empty interface (https://tour.golang.org/methods/14) works for any type at run time.
type response struct {
Bots [][]interface{} `json:"bots"`
Total int `json:"_total"`
}
Then, as you iterate through each item in the slice, you can check its type using reflection.
It would be ideal for the API to return data in a schema where every JSON array element has the same JSON type as every other element in its array. This will be easier to parse, especially using statically typed languages like Go.
For example, the API could return data like:
{
"bots": [
{
"stringProp": "value1",
"numberProps": [
1,
2
]
}
],
"_total": 1
}
Then, you could write a struct representing the API response without using the empty interface:
type bot struct {
StringProp string `json:"stringProp"`
NumberProps []float64 `json:"numberProps"`
}
type response struct {
Bots []bot `json:"bots"`
Total int `json:"_total"`
}
But sometimes you're not in control of the API you're working with, so you need to be willing to parse the data from the response in a more dynamic way. If you do have control of the API, you should consider returning the data this way instead.

How to print an object as JSON to console in Angular2?

I'm using a service to load my form data into an array in my angular2 app.
The data is stored like this:
arr = []
arr.push({title:name})
When I do a console.log(arr), it is shown as Object. What I need is to see it
as [ { 'title':name } ]. How can I achieve that?
you may use below,
JSON.stringify({ data: arr}, null, 4);
this will nicely format your data with indentation.
To print out readable information. You can use console.table() which is much easier to read than JSON:
console.table(data);
This function takes one mandatory argument data, which must be an array or an object, and one additional optional parameter columns.
It logs data as a table. Each element in the array (or enumerable property if data is an object) will be a row in the table
Example:
first convert your JSON string to Object using .parse() method and then you can print it in console using console.table('parsed sring goes here').
e.g.
const data = JSON.parse(jsonString);
console.table(data);
Please try using the JSON Pipe operator in the HTML file. As the JSON info was needed only for debugging purposes, this method was suitable for me. Sample given below:
<p>{{arr | json}}</p>
You could log each element of the array separately
arr.forEach(function(e){console.log(e)});
Since your array has just one element, this is the same as logging {'title':name}
you can print any object
console.log(this.anyObject);
when you write
console.log('any object' + this.anyObject);
this will print
any object [object Object]

Using apply on an array of objects in a json

I have a json which I am reading in R and converting to a list object. For a key "metrics", there is an array of multiple objects of the same type.
Json structure:
{"metrics":[{"metricName":"abc",
"metricType":"def"
},
{"metricName":"ghi",
"metricType":"jkl"
}]
}
This is how my list object looks like:
$metrics
$metrics[[1]]
$metrics[[1]]$metricName
[1] "abc"
$metrics[[1]]$metricType
[1] "def"
$metrics[[2]]
$metrics[[2]]$metricName
[1] "ghi"
$metrics[[2]]$metricType
[1] "jkl"
I want to apply a function (someFunc) to each object of the array. $metrics[[1]],$metrics[[2]]. How can this be done using apply family of functions?
somefunc(x){return(list(x$metricName,x$metricType)}
I tried concatenating like this:
lapply(lapply(metrics,"["),someFunc)
This does not throw an error but gives empty lists as output. The someFunc expects x$metricName,x$metricType objects to process. But using "[" does not render that kind of object I guess. Can this be handled using the apply functions?
Can you explici what your function someFunc is doing (and its parameters)?
This is working for me
someFunc=function(metricName,metricType){
return(paste(metricName,metricType))
}
metrics=list(list(metricName="abc",metricType="m"),
list(metricName="gg",metricType="L"))
lapply(metrics,FUN=function(el){someFunc(el$metricName,el$metricType)})
(use sapply eventually if you want to have a vector.

JSON data and deserialize

What is meant by deserializing json data.? What is the need to do it? I have been told to do this in my project when given a json object like this:
###format of a json record in a json file with .json extension
####
'''{
"firstname":"stack",
"lastname":"overflow",
"age":xx,
"height":x.y,
"phonenumbers":[
{
"type":"home","number":"xx-xx.xxx.x.x.x"
},
{
"type":"fax","number":"x.x.x.x.x,x,x.x.x.x"
}
]
}
'''
defining a class object
It means converting a JSON string into an object in your programming language, such as a Java POJO, a Ruby hash, a JavaScript object, etc.
The purpose is to allow your programming language to read and manipulate the data contained therein.

Parse a large file of non-schematized json using Jackson?

I have a very large .json file on disk. I want to instantiate this as a Java object using the Jackson parser.
The file looks like this:
[ { "prop1": "some_value",
"prop2": "some_other_value",
"something_random": [
// ... arbitrary list of objects containing key/value
// pairs of differing amounts and types ...
]
},
// ... repated many times ...
{
}
]
Basically it's a big array of objects and each object has two string properties that identify it, then another inner array of objects where each object is a random collection of properties and values which are mostly strings and ints, but may contain arrays as well.
Due to this object layout, there isn't a set schema I can use to easily instantiate these objects. Using the org.json processor requires attempting to allocate a string for the entire file, which often fails due to its size. So I'd like to use the streaming parser, but I am completely unfamiliar with it.
What I want in the end is a Map where the String is the value of prop1 and SomeObject is something that holds the data for the whole object (top-level array entry). Perhaps just the JSON which can then be parsed later on when it is needed?
Anyway, ideas on how to go about writing the code for this are welcome.
Since you do not want to bind the whole thing as single object, you probably want to use readValues() method of ObjectReader. And if structure of individual values is kind of generic, you may want to bind them either as java.util.Maps or JsonNodes (Jackson's tree model). So you would do something like:
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(Map.class); // or JsonNode.class
MappingIterator<Map> it = reader.readValues(new File("stuff.json"));
while (it.hasNextValue()) {
Map m = it.nextValue();
// do something; like determine real type to use and:
OtherType value = mapper.convertValue(OtherType.class);
}
to iterate over the whole thing.