getstructurevalue(
is incredibly useful for accessing a JSON structure imported into a Panorama variable or field. However, the exact nature of the structure might not be known in advance, or it might be somewhat loose, for instance a dictionary might contain values each of which could be either a single text item or an array of text items. Thus, the value returned by getstructurevalue(jsonimport(Some_JSON_data))
might be of unknown type, and dictionaries, data arrays and simple variables eah need to be treated differently…
Looking for a function to find the type of data returned by a getstructurevalue(
call, I first tried datatype(
. This is intended to find the type of data held in a variable or field, so the first thing I realised was that it can only test data already held in a variable, rather than take a function as its argument. That’s not likely to be a problem very often because the result of getstructurevalue(
would usually need to be stored somewhere anyway.
However, for both data arrays and dictionaries it returns the same data type, ‘Binary’. Fair enough I suppose in the general case, where a binary field might be used to store one of many data types: a dictionary or a data array, but also a rectangle, image files, etc. But not very helpful in this case.
As far as I can tell, importing JSON data into a Panorama variable or field could only result in a maximum of five data types — Integer, Float, Text, data array or dictionary — any of which might then be returned by getstructurevalue(
. I’m guessing the quickest way to test a structure with Binary data type is to try accessing it as a data array and, if that gives an error, assume for this purpose it must be a dictionary instead. This is the best test function I can come up with to distinguish between them:
let Data=parameter(1)
let Type=datatype(Data) // argument must be a variable not parameter( function
if Type="Binary"
Type=catcherror("Dictionary",array(Data,1))
if Type<>"Dictionary"
Type="Array"
endif
endif
functionvalue Type
It’s no use in the general case when it might also be one of several more binary data types or just any old binary data loaded from a file, but it’s good enough for testing the types resulting from importing JSON data. This is what it returns:
1 ==> "Integer"
1.1 ==> "Float"
"1" ==> "Text"
dataarray(1) ==> "Array"
jsonimport('[1]') ==> "Array"
initializedictionary("A",1) ==> "Dictionary"
jsonimport('{"A":1}') ==> "Dictionary"
Is there a better approach? And, although backward compatibility means the existing datatype(
function must continue returning ‘Binary’ in all those cases, how hard would an alternative function be to distinguish not just the simple number and text data types but also as many of the possible binary types as possible? — obviously valid dictionaries and data arrays, but also bytes, words, longwords and longlongwords for sequences of 1/2/4/8 bytes, rectangles (if a 32-byte sequence can be proved to be a valid rectangle), etc., and only returning ‘Binary’ if a block of data can’t be proved to hold a valid Panorama data type.