New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON string to Map/List #20295
Comments
Hello and thanks for the report! I'm not surprised this doesn't behave as expected today, but I think it's reasonable to want. Note that we're currently in the process of revamping our IO implementation and will be implementing a new strategy for handling JSON more naturally. We'll try to keep this case in mind as we do, but this effort is a bit extensive so it might be a while before you see it available. |
I'm nothing like a JSON expert, but am wondering whether—in the meantime before the new JSON encoder that Lydia mentions here—it might be possible to use the regex package on the string in question (or maybe just string operations themselves) in order to manually parse the string and populate the map or list as you go? I suppose the answer to that might depend on how simple/flat/straightforward the JSON string is vs. the extent to which it's deeply hierarchical or contains challenging special cases like escape characters and the like. E.g., I'm imagining something like a |
Thank you both for the update. @bradcray - I think for the time being we have a work around in place that fits our needs. We ended up needing more information for components so a simple map actually would have ended up a bit more complicated overall. For the time being, I think we are good with the current functionality, but I am very excited to see the updated JSON handling when it is available. |
Great, thanks for the update Ethan. |
@lydia-duncan, @bradcray - I just wanted to get an update on this because it is still causing a lot of heartburn for Arkouda. We are increasingly seeing instances where we need to take a json formatted string and create a |
Noting that using use IO, Map;
var m: map(keyType=string, valType=string);
readf("%jt", m);
writeln(m); |
This will be a bit of a long response, so I'll try to summarize the main points here:
Also, JSON requires double-quotes for strings, and I don't think single-quotes are allowed, so all my examples will be using double-quotes. Historically we have supported use IO;
use Map;
proc main() {
var json_str = '{"key1": "val1", "key2": "val2"}';
var newmem = openMemFile();
newmem.writer().write(json_str);
var nreader = newmem.reader();
var m: map(keyType=string, valType=string);
// note: 'readThis' is meant for the IO module to invoke, not users
// m.readThis(nreader);
// instead use...
nreader.readf("%jt", m);
writeln(m);
// prints (in Chapel's default format, not JSON)
// {key2: val2, key1: val1}
} The I tested various types of data, which I will list here. You should be able to read these JSON objects into the noted Chapel types:
There are some other examples in the PR that demonstrate success working with records that contain simple types. "Serializers" are a new feature we are working on to replace use IO;
use Map;
use Json;
proc main() {
var json_str = '{"key1": "val1", "key2": "val2"}';
var newmem = openMemFile();
newmem.writer().write(json_str);
var nreader = newmem.reader(deserializer=new JsonDeserializer());
var m : map(keyType=string, valType=string);
nreader.read(m);
// Alternatively, no need to default-initialize the map
//var m = nreader.read(map(string,string));
writeln(m);
} Writing A nice feature of the JsonSerializer is that it can convert non-string map keys into strings, and vice versa. For example, representing a
This functionality can also support using a record as a key. I can speak more to that if anyone's interested. Some advantages of serializers:
This is a relatively recent feature that still needs to undergo some review, but I believe the example code using Serializers have been a focus of mine recently, so if there's some particular use-case you are concerned about, I'd be interested in hearing more! I hope this work will help to relieve the issues you are running into. |
@benharsh - thanks for the info. Are the serializers available in Chapel 1.30? I tried adding the serializer code in for a case and it is not found. I wasn't able to find it in the Chapel docs either, but maybe I did not look hard enough. Maybe I am jumping ahead and these are not yet available and if so no problem, I look forward to the addition. I have tried using
This string is generated using
|
Sorry for not being clear, the serializers are not available in 1.30 as the API needs more discussion before stabilizing, and because the implementation was also not ready for 1.30. The use IO;
use Map;
proc main() {
var f = openMemFile();
{
// syntax highlighting isn't great here, but """ indicates an uninterpreted string literal
var str = """{"codes": "id_OACLOtw_12", "categories": "id_OACLOtw_18", "NA_codes": "id_OACLOtw_19", "permutation": "id_OACLOtw_8", "segments": "id_OACLOtw_7"}""";
f.writer().write(str);
}
{
var r = f.reader();
var m : map(string, string);
r.readf("%jt", m);
writeln(m); // printing in the "default" format
}
} This program prints:
|
@Ethan-DeBandi99 has confirmed that Ben's PR worked for him, so I'm closing this as resolved by #22279 and it'll be available in Chapel 1.31. |
(Thanks for the quick turnaround once this got marked as high priority, @benharsh!) |
Summary
Steps to Reproduce
Source Code:
Please note: Single quotes used here, but have also tried with
\"
. Is this correct? It works when reading into a record.Produces This Error
I receive similar error messages to the above for reading in a list. I did not provide additional source code because it is essentially the same, but I can provide it if needed.
chpl --version
printchplenv
The text was updated successfully, but these errors were encountered: