Casting JSONValues arrays to native arrays ... ??? ...
Steven Schveighoffer
schveiguy at gmail.com
Thu Sep 23 19:04:47 UTC 2021
On 9/23/21 2:20 PM, james.p.leblanc wrote:
> Dear D-ers,
>
> In attempting to cast JSONValues that hold arrays to "native" array types,
> I have hit some issues. Example code:
>
> ```d
> import std.stdio;
> import std.json;
>
> void main(){
>
> JSONValue jj;
> jj["d"] = [ 1.234 ]; // a "dummy" double value
> jj["ba"] = [ true, false, true]; // "ba" boolean array
Note that this creates a JSONValue array which *copies* the values of
the boolean array, converting them to JSONValue (which is what a
JSONValue array stores).
>
> writeln("typeid(jj): ", typeid(jj), ", jj: ", jj );
>
> // various things that I thought might work, but do NOT
>
> auto z1 = cast(bool) jj["ba"]; // attempt #1
A JSONValue cannot be cast to a boolean (it does not provide the
appropriate opCast)
> auto z2 = cast(bool[]) jj["ba"]; // attempt #2
> auto z3 = cast(bool) jj["ba"].array; // attempt #3
These try to cast something that is not an array to an array or vice
versa. These are not supported unless the type itself has an `opCast`
overload.
> auto z4 = cast(bool[]) jj["ba"].array; // attempt #4
Casting one array type to another is like pointing at the array that
represents the original type *as if* it were of the new type. No
translation is made, you are pointing at the same memory! The length is
adjusted based on the size of the original array element and the size of
the new one.
For instance:
```d
int[] arr = [1];
auto a2 = cast(ubyte[])arr;
assert(a2.length == 4);
assert(a2 == cast(ubyte[])([1, 0, 0, 0])); // assuming little endian
```
>
> However, if I comment out the offending attempts (1, 2, and 3), then it
> compiles, and can run ... but produces a result which I very much do NOT
> understand:
>
> typeid(jj): std.json.JSONValue, jj:
> {"ba":[true,false,true],"d":[1.23399999999999999]}
> typeid(z4): bool[], z4: [false, false, false, false, false, false,
> false, false, false, false, false, false, false, false, false, false,
> true, false, false, false, false, false, false, false, false, false,
> false, false, false, false, false, false, false, false, false, false,
> false, false, false, false, true, false, false, false, false, false,
> false, false, false, false, false, false, false, false, false, false,
> false, false, false, false, false, false, false, false, true, false,
> false, false, false, false, false, false]
This is an array of JSONValue, with each byte interpreted as if it were
a bool.
> Hmmmm... is there a standard way to push these JSONValues into nice native
> array types? (The real code is eventually going to be using traits and
> mixins
> ... but I do not think this should pose additional problems).
How you really do this:
```d
import std.algorithm : map;
auto z5 = jj["ba"] // get the JSONValue that is at the key "ba"
.map!(v => v.get!bool) // map each value into a boolean
.array // create an array out of the results;
assert z5 == [true, false, true];
```
(warning, untested)
-Steve
More information about the Digitalmars-d-learn
mailing list