I am parsing a JSON object containing several key value pairs but am not sure how to make objects out of the JSON below. The keys are always different depending on the GET request so I am not able to use json['keyname'] like usual. What kind of function would I need in order to return a list of keys from 'ccwms' and a respective list of values (floats)?
{
"ccwms": {
"frc118": 160.8076758518209,
"frc1255": 15.257951313413884,
"frc1296": 11.42077882954301,
"frc7321": -161.58464745359254
}
}
After parsing the JSON, you have a normal Dart Map with string keys and some values. You can iterate maps in several ways, for example:
for (var key in map.keys) { doSomething(key, map[key]); }
for (var entry in map.entries) { doSomething(entry.key, entry.value); }
map.forEach(doSomething);
(Map.keys, Map.entries, Map.forEach).
I'm sure there are more ways to access all the keys and values.
What you do with the keys and values is up to you, it's just a map.
Minimal Dart program to convert a json string:
import 'dart:convert';
main() {
String source = """{"X":"RRRR","Y":"SSSS","ccwms": {
"frc118": 160.8076758518209,
"frc1255": 15.257951313413884,
"frc1296": 11.42077882954301,
"frc7321": -161.58464745359254
}}""";
dynamic target = JsonDecoder().convert(source);
print ( source.toString());
}
Are these keys random ? I think keys have to be predefined set, because json is a serialization for already existed object and the object structure can not be random
hope I understand correctly
should be a comment but I can not add comments right now.
Related
The Problem
I am trying to generate a json object (with serde) by parsing a custom macro format that looks like this:
Plot.Polar.max: 20
Plot.Polar.min: 0
Plot.Polar.numberlabel: 0101
Plot.Polar.chartname: small-chart
Plot.Polar.Var.1:
Plot.Polar.Var.2: A label: with T+ES[T] #Data
What I get stuck on is how to set the keys for the object. In my old JavaScript code I split on \n, ., and :, had a couple of nested loops, and a reduceRight in the end to create the object like this:
// rowObject equals one row in the old macro format
let rowObject = keys.reduceRight(
(allKeys, item) => ({ [item]: allKeys }),
val,
);
My Goal
My goal is to use that json object to generate a highcharts config (json) depending on the keys and values from the custom macro. I want to be able to print just the macro in json format as well hence why I want to convert the macro to json first and not use a separate data structure (though that might be a good idea?). The json I want to produce from the macro is this:
{
"Plot": {
"Polar": {
"max": 20,
"min": 0
}
}
}
What I Have Tried
Map::insert though I am not sure how to structure the key string. How do I manage the Map objects in this case?
Another solution I see is creating the object from a raw string and merging each rowObject with the main object though this approach feels a bit hacky.
The current loop I have:
// pseudo
// let mut json_macro = new Map();
for row in macro_rows.iter() {
let row_key_value: Vec<&str> = row.split(':').collect();
let keys = row_key_value[0];
let value = row_key_value[1];
let keys_split: Vec<&str> = keys.split('.').collect();
for key in keys_split.iter() {
// TODO: accumulate a objects to row_object
}
// TODO: insert row_object to json_macro
}
The Question
Is it possible to do something like reduceRight in JavaScript or something similar in rust?
Update
I realized that I will have to treat all values as strings because it is impossible to know if a number is a string or not. What worked in the end was the solution #gizmo provided.
To insert your row into json_macro you can fold keys_split from the left and insert every key into the top-level object:
let row_key_value: Vec<&str> = row.split(':').collect();
let keys = row_key_value[0];
let value: Value = serde_json::from_str(row_key_value[1]).unwrap();
let keys_split: Vec<&str> = keys.split('.').collect();
keys_split[..keys_split.len() - 1]
.iter()
.fold(&mut json_macro, |object, &key| {
object
.entry(key)
.or_insert(Map::new().into())
.as_object_mut()
.unwrap()
})
.insert(keys_split.last().unwrap().to_string(), value);
A couple things to note here about unwrap()s:
from_str(...).unwrap(): I parse val as a JSON object here. This might not be what you want. Maybe instead you want str::parse::<i32> or something else. In any case, this parsing might fail.
.as_object_mut().unwrap(): This will explode if the input redefines a key like
Plot.Polar: 0
Plot.Polar.max: 20
The other way around, you probably want to handle the case where the key is already defined as an object.
keys_split.last().unwrap() won't fail but you might want to check if it's the empty string
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.
I'm trying to learn to import JSON files into p5.js.
I'm using this list of English words: https://raw.githubusercontent.com/dwyl/english-words/master/words_dictionary.json
I already know how to import things when the entries are organized into respective categories. It seems every entry is in the same array, though. How can I import individual entries?
In this particular case the data you're loading isn't a regular array ([]) with values accessed using an integer index, but a JavaScript Object or associative array({}) with values accessed using a string instead of an integer index.
This is a key-value pair association.
Let's say you have a simple association:
let data = {
"firstName": "Nicholas",
"lastName": "Keough",
}
In the example above firstName and lastName are keys and "Nicholas" and "Keough" are values.
You can use array like [] and instead of an integer index, you'd use the key:
console.log(data["firstName"]);// prints "Nicholas"
console.log(data["lastName"]);// prints "Keough"
alternatively you can use dot notation:
console.log(data.firstName);// prints "Nicholas"
console.log(data.lastName);// prints "Keough"
In your case, let's say dictionary is a variable that holds the loaded JSON data,
you apply the same ideas above to access each word. For example:
console.log(data['absorbent']);//prints 1
or
console.log(data.absorbent.);//prints 1
If you need to loop over the values (and in your case, with the dictionary of 370101 values, you would really want to), you can use a for...in loop.
Alternatively, if you simply need to access the keys, not the values, as a single array you can use Object.keys()
Here's a basic example illustrating both options:
(Bare in mind the dictionary is large so it will take time to load and print the data to console)
let dictionary;
// preload JSON data
function preload(){
dictionary = loadJSON("https://raw.githubusercontent.com/dwyl/english-words/master/words_dictionary.json");
}
function setup(){
noLoop();
console.log('test');
// access JSON data with a for...in loop
for(let word in dictionary){
console.log("word: " + word + " value: " + dictionary[word]);
}
// optionally, access the associative array keys only as an array
console.log(Object.keys(dictionary));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
In kotlin i have a response like that:
"nameIdPairs":{"name1":"590f7340a1fc", "name2":"590f7340a1fc"}}
since key and value is not determined before, it changes continuosly. Therefore, i cannot use data class. I get this response with JsonObject but i need to extract "name1" and "590f7340a1fc" seperately. What are the possible ways to do it in Kotlin?
for (key in myListTypes.keySet()) {
myListTypes.get(key).toString()
}
works for me!
My previous problem was I'm unable to arrange the json structure like what I wanted. And I found some answers that looks like it almost satisfy my needs but unfortunately I don't know if it's working or not because another problem has occurred.
Below, I arranged my own json data based on the json structure by someone named Programmer.
{
"dialog_type": {"human": {"inner": "He is so scary"}}
}
Here, I have a key called "human". I have two keys in my data. First is "human" and second is "non_human". Now if I have two data in my json file, it will become like this :
{
"dialog_type": {"human": {"inner": "He is so scary"}}
},
{
"dialog_type": {"non_human": "Once upon a time..."}
}
This case is maybe simillar to someone asked here. But unfortunately I have no idea if it's possible to do that in unity. I want to make a method like this answer. So I can determine what action to take by comparing those keys.
Now the question is how do I get the key name as a string in my json data using C# ?
To access the property names of a Unity javascript object, you can use:
for(var property in obj) {}
For instance, this will log all keys (i.e. property names) of all the property key-value pairs in a Unity javascript object (e.g. "key1" and "key2"):
function Start () {
var testObject = {
"key1": "value 1",
"key2": "value 2"
};
for(var property in testObject) {
Debug.Log(property.Key);
};
}
That should give you a way to check objects for any matching property names you are interested in.