JSON
JSON (JavaScript Object Notation) is a lightweight, text-based format designed for structured data interchange. It represents data objects consisting of key–value pairs and arrays, and it is entirely language-independent.
JSON Datatypes
JSON consists of six fundamental data types used to represent structured data:
- String
- It is a text enclosed in double quotes. For example, "name": "Alice".
- Number
- It is integers or floating-point numbers.
- They have no quotes, no leading zeros (e.g., 03562), and no special values like NaN or Infinity. For instance, "age": 30, "score": 95.5.
- Boolean
- It represents logical values: true or false (without quotes). For example, "isActive": true.
- Null
- It symbolizes a null or an empty value. For instance, "middleName": null.
- Array
- It is an ordered list of values (can be of any data type, including nested arrays/objects). For example, "colors": ["red", "green", "blue",{ "additional": "black" },"1Bx124s"].
- Object
- It is a collection of key/value pairs (e.g., a dictionary or map).
- Keys must be strings, whereas values can be any JSON type. Example:
How InterSystems IRIS Creates and Manipulates JSON
InterSystems IRIS provides several simple and efficient methods for creating and interacting with standard JSON data structures:
- JSON literal constructors in ObjectScript syntax
- %DynamicObject and %DynamicArray class definitions with their APIs for serialization and deserialization
- JSON_OBJECT, JSON_ARRAYAGG and JSON_TABLE functions for SQL
JSON Literal Constructors
JSON literal constructors in ObjectScript syntax enable the creation and modification of JSON structures in a highly flexible and intuitive manner. This approach allows you to define dynamic entities by directly assigning a JSON string to a variable, simplifying JSON data handling.
When JSON is created using literal constructors, InterSystems IRIS automatically instantiates the appropriate %DynamicObject and %DynamicArray object classes. It provides direct access to object model capabilities, allowing you to manipulate instance methods without explicit object creation.
Dynamic Object Example
Multiple Ways to Construct JSON in IRIS
InterSystems IRIS offers flexibility in how you construct and assign JSON data. You can either use a single-line literal constructor or build the JSON object step-by-step utilizing dynamic object syntax. The resulting structure is always a fully-typed %DynamicObject that inherits all the behaviors and methods available to %DynamicObject.
Method 1: Literal JSON Construction
You can define the entire JSON structure in one line, including ObjectScript expressions that are evaluated at runtime:set json =
Set json= {
"name": "test,patient",
"title": "Mr",
"p_age": ($H - $ZDateH("12/01/1990") \ 365),
“isActive”: true
}
In this example the values stand for the following:
- "p_age" is an expression evaluated at runtime, based on the difference between the current date ($Horolog) and a specific birth date.
- "isActive" directly declares a JSON Boolean true value.
Method 2: Step-by-Step Dynamic Assignment
Alternatively, you can build the JSON object by setting each key-value pair individually:
Set json = {}
Set json.name = "test,patient"
Set json.title = "Mr"
Set json."p_age" = ($Horolog - $ZDateH("12/01/1990") \ 365)
This approach is helpful in the following cases:
- Values are derived conditionally.
- You want to build the object incrementally.
- Code clarity and maintainability are priorities.
Method 3: Build a DynamicObject Using Methods
You can build a %DynamicObject incrementally with the help of the %Set() method that lets you define the values below:
- The key (1st argument)
- The value (2nd argument)
- The data type (optional 3rd argument)
To ensure the correct JSON data type is employed for the value, you can explicitly specify the type as the third parameter.
Set json = {}
Do json.%Set("name", "test,patient")
Do json.%Set("title", "Mr ")
Do json.%Set("p_age", ($Horolog - $ZDateH("12/01/1990") \ 365), "number")
Do json.%Set(“IsActive”,1,”Boolean”)
Dynamic Array Construction in IRIS
Similar to dynamic objects, dynamic arrays in InterSystems IRIS can be constructed with either a single-line literal constructor or a step-by-step dynamic assignment approach.These arrays are instances of %DynamicArray and can hold mixed data types, including objects, numbers, strings, booleans, and runtime expressions.
Method 1: Literal JSON Array Construction
You can define a JSON array in a single line utilizing the array literal syntax. The resulting structure is a fully-typed %DynamicArray object that inherits all the behaviors and methods available to %DynamicArray.
set array = [1, "test", 12.32565, 0.01548, {"name": "test"}, 1.00000, ($ZVersion), true]
Note for this example:
- The array includes integers, strings, decimals, a nested object, a runtime-evaluated expression ($ZVersion), and a Boolean.
Method 2: Step-by-Step Dynamic Assignment
Method 2.1: Set Values in a Dynamic Array by Index
A %DynamicArray in InterSystems IRIS is an ordered collection of values, where each element is accessed by its index, starting from 0.
You can assign values directly to specific indices. If you skip any intermediate positions, those indices remain unassigned internally. However, for serialization purposes (e.g., when using ZWrite or %ToJSON()), IRIS automatically displays unassigned elements as null to maintain a valid JSON structure.
This means there is a distinction between how the data is stored and how it is represented: unassigned elements are not truly null unless explicitly set, but they appear as null when the array is output or serialized. You can determine the type of a value using the %GetTypeOf() method.
Example:
USER>Set array = []
USER>Set array."1" = "test"
USER>Set array."5" = "hello"
USER>Write array.%ToJSON()
array=[null,"test",null,null,null,"hello"]
Although the output shows null at index 0, it is crucial to note that the value was never explicitly set. Therefore, calling array.%GetTypeOf(0) will return "unassigned", indicating that the index exists only for display purposes and has not been initialized with a value.
Method 2.2: Build a DynamicArray Using Methods
You can incrementally construct a %DynamicArray by using the built-in %Push() method. This approach appends values to the end of the array in the order they are added.
set array = []
do array.%Push(1)
do array.%Push("test")
do array.%Push({"name": "test"})
do array.%Push($Piece($zversion, " ", 1, 5))
Do array.%ToJSON()
#
Output
[1,"test",{"name":"test"},"IRIS for Windows (x86-64) 2024.1.1"]
This method is practical in the following cases:
- Array elements are determined dynamically.
- You are constructing the array conditionally or iteratively.
- You want more control over the data being inserted.
Detailed Overview of JSON Key-Value Assignment
Assigning Runtime Values in JSON (IRIS)
InterSystems IRIS supports both static and dynamic value assignment within JSON structures. When working with the literal constructor syntax ({} or []), any extended expression enclosed in parentheses is evaluated at runtime.
For example:
USER>Set json = {"version":($ZVersion)}
USER>ZWrite json
json={"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}
In this case, the value of the "version" key is dynamically evaluated using the $ZVersion system variable at runtime. it allows you to embed real-time system or application data directly into your JSON structures.
Number Representation and Assignment in JSON
An ObjectScript Decimal Floating-Point number and an IEEE Binary Floating-Point number do not track trailing zeros in decimal representation (e.g., 12.3, 12.30, and 12.3000). However, in JSON, numbers are represented as text in decimal or scientific notation (aka exponent form). While JSON syntax supports scientific notation (e.g., 1.23e4), it does not mandate any internal binary representation. It means that JSON numbers can preserve trailing zeros when created using literal constructors with square brackets [] or curly braces {}, as these constructors parse values utilizing JSON syntax that maintains formatting details. Chek out the example below:
USER> Set json = {"decimal":1.00000}
USER> ZWrite json
{"decimal":1.00000}
Here, the trailing zeros are preserved in the JSON object representation.
Scientific Notation
InterSystems IRIS preserves scientific notation and trailing zeros in JSON, allowing you to set and view values in exponent form. The number retains this format until it is explicitly written or serialized.
However, note that numbers supported by JSON can exceed the capacity of the internal representations backed by ObjectScript. Rounding or overflow can occur when converting a JSON numeric value for use in an ObjectScript expression. For example:
USER>SET z=[3E400] ; No error placing a large JSON number into a %DynamicArray
USER>WRITE z.%Get(0) ; But converting the JSON number gets a <MAXNUMBER> signal
Step-by-Step Way
USER>Set json = {}
USER>Set json."e_exponent"=1E5
USER>ZWrite json
json={"e_exponent":100000}
In this example, the following happens:
- The value 1E5 (scientific notation for 100,000) is treated as a numeric expression.
- IRIS evaluates the dynamic expression at runtime and stores the computed result (100000) as the actual value of the "e_exponent" key.
Unicode Translation
Unicode Handling in Literal Constructors – IRIS JSON
In InterSystems IRIS, when working with the literal constructor syntax for dynamic arrays, each element is assessed at runtime. It means that you can mix standard JSON strings and ObjectScript expressions, including those involving Unicode characters, and IRIS will store the evaluated results.
Example: Mixed Input, Same Result
USER>Set array = ["\u00E9", "cach\u00E9", ("cach"_$CHAR(233))]
USER>ZWrite array
array=["é","caché","caché"]
- "\u00E9" is interpreted as the Unicode character é.
- "cach\u00E9" becomes caché when parsed.
- ("cach"_$CHAR(233)) is an ObjectScript expression that concatenates "cach" with the character é (Unicode 233).
All three inputs result in identical strings: "é" and "caché".
When Unicode Escapes Are Passed as Expressions
If you wrap a Unicode escape string in parentheses (making it an expression), IRIS treats it as a plain string literal, not as a Unicode escape.
USER>Set array = ["cach\u00E9", ("cach\u00E9")]
USER>ZWrite array
array=["caché","cach\\u00E9"]
- The first element "cach\u00E9" string literal is parsed as JSON and becomes caché. When a string literal directly appears as an element within the literal constructor syntax (which functions as a JSON array literal in ObjectScript), IRIS treats this as a JSON string literal context
- The second element ("cach\u00E9") is treated as a ObjectScript string literal and it evaluated as runtime expression, so the \u is not parsed as Unicode. It stays escaped as \\u00E9.
Assign Null Values
IRIS provides a straightforward way to assign a null value to a key in a JSON key-value pair.
For example:
USER>Set json = {"isActive":null}
USER>ZWrite json
json={"isActive":null}
It sets the "isActive" key to null within the JSON object, with the help of the native dynamic object syntax in IRIS.
Using Comments Inside JSON Constructors in IRIS
Unlike strict JSON parsers (which do not allow any comments), InterSystems IRIS provides the flexibility to include comments within JSON literal constructors ({} or []). It can significantly enhance code readability and maintainability.
Block Comments (/* */) in Arrays and Objects
IRIS allows you to insert block-style comments (/* comment */) anywhere within JSON constructors (both arrays and objects). However, note that // line comments are not allowed inside single-line array/object declarations.
set array = [1, "test" /* test comment */, "hello world", ($Horolog)]
set array = [
1,
"test" ,
"Hello world",
($Horolog)
]
- It is valid in IRIS.
- It is useful for documenting array elements.
Block and Line Comments in JSON Objects
IRIS also allows both /* block comments */ and // line comments inside object constructors:
set json = {
"name": "test",
"age": (age)
}
/* ... */
can be used after any key-value pair.
// ...
can be placed after a pair as well
Create JSON with Class Definitions
The %DynamicAbstractObject (%DAO) subclasses, including the %DynamicArray and %DynamicObject classes, are the primary classes for creating, modifying, and sending JSON representations into and out of InterSystems IRIS databases.
These classes support object manipulation using such ObjectScript intrinsic functions as $Property and $Method.The %DynamicObject implementation does not maintain a predefined list of valid property names, as all string keys are considered legal and valid.
Instead of employing %Get and %Set dedicated methods for DynamicObject and DynamicArray, you can also retrieve values dynamically with the $Property and $Method intrinsic functions.
However, $Property is generally more efficient than $Method, and is therefore recommended when accessing values in %DynamicObject instances.
ClassMethod sample()
{
#dynamic object
Set do = {"1D":"test"}
Set $Property(do, "id")=12
Do $Method(do, "%Set", "version", $ZV, "string")
ZWrite do
#
Set da = []
#
Set $Property(da, "0")=12
Do $Method(da, "%Set", "4", $ZV)
Zwrite da
}
DynamicObject
USER>Set do = {"1D":"test","version":($Piece($ZVersion," ",1,5))}
USER>Write $Property(do,"1D")
test
USER>Write $Method(do,"versionGet")
IRIS for Windows (x86-64) 2024.1.1
DynamicArray
USER>Set da = [1,($USERNAME),($ROLES)]
USER>Write $Property(da,1)
Test
USER>Write $Method(da,"%Get",2)
All
Code Sample
The following provides ObjectScript and Embedded Python code samples for %DynamicObject creation (for IRIS 2024.1 and 2025.1 versions).
Set dynObject1 = ##class(%DynamicObject).%New()
Set dynObject1.MRN = 4298598
Set dynObject1.name = "test,Patient A"
Set dynObject1.IsActive = 1
Set dynObject1.emails = ##class(%DynamicArray).%New()
Set dynObject1. emails."0" = "test@gmail.com"
Set dynObject1. emails."1" = “test1@gmail.com”
Embedded Python sample
import iris
dynObject1 = iris.cls("%DynamicObject")._New()
dynObject1._Set("MRN",298598)
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
emails = iris.cls("%DynamicArray")._New()
emails.add("test@gmail.com")
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())
Embedded Python 2025.1
Simplified Class Method Access in Python
Instead of operating the iris.cls("ClassName").method() syntax, you can directly access class methods with the iris.ClassName.method() format for improved readability and convenience.
# Traditional syntax
iris.cls("Sample.Person")._New()
# Simplified syntax
iris.Sample.Person._New()
# For system classes
iris.cls("%DynamicObject")._New()
iris._Library.DynamicObject._New()
This approach provides a more Pythonic and concise way to interact with InterSystems IRIS classes.
2025.1 Embedded Python sample
import iris
dynObject1 = iris._Library.DynamicObject._New()
dynObject1._Set("MRN",298598)
dynObject1._Set("name" , "test,Patient A")
dynObject1._Set("IsActive", 1, "boolean")
emails = iris._Library.DynamicArray._New()
emails.add("test@gmail.com")
emails.add("test1@gmail.com")
dynObject1._Set("emails", emails)
print(dynObject1.toString())
Methods of %DynamicObject and %DynamicArray
A set of commonly used and practical methods is available for working with JSON in InterSystems IRIS. These methods are essential for efficiently creating, modifying, and deleting JSON objects and arrays.
%IsDefined(Key)
The %IsDefined method checks whether a specified key exists in the object. It returns a Boolean value: 1 if the key is present, or 0 if it is not. Note that key matching is case-sensitive.
USER>Set json = {"username":"TestUser", "role":"All"}
USER>Write json.%IsDefined("username")
1
USER>Write json.%IsDefined("password")
0
USER>Write json.%IsDefined("userName")
0
Embedded Python - contains(key)
The Python contains function checks if a specified key exists in a DynamicObject or DynamicArray. It returns 1 if the key is present, and 0 if it is not.
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAOIsDefined()
{
Set json = {"username":($USERNAME), "roles": ($ROLES), "horolog":(+$H)}
Do ..DAOIsDefinedPY(json,"horolog")
}
ClassMethod DAOIsDefinedPY(dao, key) [ Language = python ]
{
# use contains instead of %IsDefined method
print(dao.contains(key))
}
}
Output
USER>DO ##class(Sample.DAO.EmpeddedPY).DAOIsDefined()
1
%Get(Key, Default, Type)
The %Get is an instance method used to retrieve values from a %DynamicObject or %DynamicArray. When you work with the %Get(key) method to evaluate a property containing a JSON representation, that JSON representation will first be converted into an ObjectScript value, and then it will return that value.
This method accepts 3 formal parameters:
- Key (required)
- objects: the name of the key to retrieve.
- arrays: the index position of the element.
- Default (optional)
- The value to return if the key or index is not present.
- If omitted and the key is missing, an empty string is returned.
- Type (optional but important)
- This is the most crucial parameter when handling large strings. If the JSON contains a large string exceeding the IRIS maximum string length (3,641,144), get the maxstring by ($SYSTEM.SYS.MaxLocalLength() / $$$MaxLocalLength / $$$MaxStringLength). You can also pass this parameter with one of the following values to prevent a <MAXSTRING> error:
Apart from the abovementioned types, it might also signal < ILLEGAL VALUE> error in the next cases:
- To handle large string values efficiently, use the "stream" type. It returns a stream object (e.g., %Stream.DynamicCharacter) instead of loading the entire string into memory.
Example: Set stream = json.%Get("image", , "stream")
- If you want to retrieve the value as a Base64-encoded string, go for the "string>base64" type. Example: Set data = json.%Get("image", , "string>base64")
- To decode a Base64-encoded string and get the original value, utilize the "string<base64" type. Example: Set data= json.%Get("b64_encode", , "string<base64")
- By default, %Get converts JSON values to their corresponding ObjectScript types. To retrieve the original JSON representation instead (e.g., true, null), specify "JSON" as the third parameter. Here is how it works in detail:
Set json = {"IsActive": true, "IsNull": null}
By default, retrieving "IsActive" returns 1, and "IsNull" returns an empty string (""). It happens because JSON values are automatically converted to their ObjectScript equivalents.
To retrieve the original JSON representations (true and null), pass "JSON" as the third parameter in the %Get method:
USER>Set json = {"IsActive": true, "IsNull": null}
USER>Write json.%Get("IsActive")
1
USER>Write json.%Get("IsActive",,"JSON")
true
USER>Write json.%Get("IsNull")
USER>Write json.%Get("IsNull", , "JSON")
null
Generate Large JSON
The following code generates a large sample JSON as a stream.
ClassMethod LargeJSON()
{
Set $Piece(data,"a",$$$MaxStringLength)=""
#
Set stream = ##class(%Stream.TmpCharacter).%New()
Do stream.Write("{""data"": "" ")
For i=1:1:20 d stream.Write(data)
Do stream.Write(" ""} ")
Quit stream
}
Once a stream is created, convert it to JSON with the help of the %FromJSON() method. When you work with %Get() to fetch by JSON key, it might signal a <MAXSTRING> error. To prevent this, you need to pass the third parameter as "stream", and it will convert the string into a stream object (%Stream.DynamicBinary).
What is %Stream.DynamicBinary and %Stream.DynamicCharacter?
The %Stream.DynamicCharacter (%SDC) and %Stream.DynamicBinary (%SDB) classes are specifically designed to hold copies of string or binary data stored within elements of a %DynamicArray (%DA) or %DynamicObject (%DO).
These %SDC and %SDB streams are read-only, meaning their contents cannot be modified directly. However, if you need to alter the data, you can create a writable stream from the %Stream package and use the CopyFrom() method to duplicate the contents from the read-only stream into the new writable stream.
ClassMethod ParseToJSON()
{
Set stream = ..LargeJSON()
Set json = ##class(%DynamicAbstractObject).%FromJSON(stream)
Write json
Write json.%Get("data")
#
Write json.%Get("data",,"stream")
}
Embedded Python
DynamicObject
Embedded Python - get(key)
The Python get function takes one argument — the key to check for in the dynamic object.
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DOGet()
{
Set json = {"id":1234,"firstName":"Ashok","lastName":"Kumar","IsActive":true}
Do ..DOGetPY(json)
}
ClassMethod DOGetPY(dynamicObj) [ Language = python ]
{
print(dynamicObj._Get("IsActive",1,"JSON"))
# get has one parameter
print(dynamicObj.get("id"))
}
ClassMethod DAOGet()
{
Set json ={"string":"Hello, world!","number_integer":42,
"number_float":3.1415899999999999,"boolean_true":true,
"boolean_false":false,"null_value":null,
"object":{"nested_key":"nested value"},
"array":[1,"two",true,null,{"key":"value"}]
}
Do ..DAOGetPY(json,"array")
}
ClassMethod DAOGetPY(dao, key) [ Language = python ]
{
# Use the Python-specific function "get" to retrieve values from the DynamicObject/ array. No need to use %Get
print(dao.get(key).get(4).get("key"))
return 0
}
}
Output
USER>do ##class(Sample.DAO.EmpeddedPY).DOGet()
true
1234
USER>do ##class(Sample.DAO.EmpeddedPY).DAOGet()
value
DynamicArray
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAGet()
{
Set array = [1234,"ashok","kumar",{"version":($ZVersion)}]
Do ..DAGetPY(array)
}
ClassMethod DAGetPY(dynamicArr) [ Language = python ]
{
print(dynamicArr._Get(1))
print(dynamicArr.get(3)._ToJSON())
}
}
Output
USER>do ##class(Sample.DAO.EmpeddedPY).DAGet()
ashok
{"version":"IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT"}
%Set(Key, Value, Type)
The %Set instance method is used to add or modify key-value pairs in a %DynamicObject, or set indexed values in a %DynamicArray. The value assigned is evaluated as a runtime ObjectScript expression, and the result of that expression becomes the property's value.
This %Set has 3 formal parameters:
- Key (required): Represents the key in a %DynamicObject or the index in a %DynamicArray. In JSON, all object keys must be strings. If you provide a numeric key (e.g., 1), it will automatically be converted to a string.
Example: Do json.%Set(1, "test") results in {"1": "test"}.
- Value (required): The actual value that will be stored in the element. Omitting this will signal a <PARAMETER> error.
- Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly necessary when dealing with Booleans, nulls, large strings, or stream objects.
- Boolean: To set a Boolean key-value pair in JSON, note that InterSystems IRIS does not have a native Boolean type. You can pass 1 for true and specify the type as "Boolean" to store the value correctly.
Example: Do json.%Set("active", 1, "Boolean") results in {"active":true}.
- Number: To store a string as a JSON number, provide the value as a string and specify the type as "Number".
Example: Do json.%Set("int", "158425", "Number").
- Null: In IRIS, a string with a space (" ") is not automatically treated as null. To explicitly set a JSON null, use a blank string with the type "null".
Example: Do json.%Set("IsNull", "", "null") results in {"IsNull": null}.
- Stream: If the value is a stream object, you can specify the type as "stream" to automatically convert the stream content to a string before storing it in the JSON object.
- String and numeric values can be assigned directly without specifying a type.
- Base64 Encoding/Decoding: To encode a string as a Base64 value before storing it, utilize the type "string>base64".
Example: Do json.%Set("basicpassword", "_BASIC:TEST","string>base64").
- To decode a Base64 string and store the result, employ the type "string<base64".
Example: Do json.%Set("basicpassword", "X0JBU0lDOlRFU1Q=","string<base64").
- For stream content: "stream>base64"- %Stream contents are encoded into a Base64 string.
- "stream<base64"- %Stream is decoded from Base64 into a byte string.
Embedded Python
In embedded Python, you must use an underscore _ instead of a percent sign % for methods. For instance, %Get() becomes _Get() in a Python script.
DynamicObject
Embedded Python - put(key, value)
The Python put function takes two arguments: The first is the key (for a DynamicObject) or index (for a DynamicArray), and the second is the value to assign to that key or index.
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DOSet()
{
Set json = {}
Do ..DOSetPY(json)
Write json.%ToJSON()
}
ClassMethod DOSetPY(dynamicObj) [ Language = python ]
{
dynamicObj._Set("id",1234)
dynamicObj._Set("firstName", "Ashok")
dynamicObj.put("lastName", "Kumar")
#print(dynamicObj._ToJSON())
}
ClassMethod DAOSet()
{
Set json ={"string":"Hello, world!","number_integer":42,
"object":{"nested_key":"nested value"},
"array":[1,"two",true,null,{"key":"value"}]
}
Do ..DAOSetPY(json,"array")
}
ClassMethod DAOSetPY(dao, key) [ Language = python ]
{
# Use the Python-specific function "put" to retrieve values from the DynamicObject/ array. No need to use %Set
dao.get(key).get(4).put("key","changed to hello")
# use toString() function . No need to use %ToJSON()
print(dao.toString())
return 0
}
}
Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DOSet()
{"id":1234,"firstName":"Ashok","lastName":"Kumar"}
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}
DynamicArray
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DASet()
{
Set array = ##class(%DynamicArray).%New()
Do ..DASetPY(array)
Write array.%ToJSON()
}
ClassMethod DASetPY(dynamicArr) [ Language = python ]
{
dynamicArr._Set(0, 1234)
dynamicArr._Set(1, "Ashok")
dynamicArr.put(2, "Kumar")
#print(dynamicObj._ToJSON())
}
}
Output
USER> Do ##class(Sample.DAO.EmpeddedPY).DASet()
[1234,"Ashok","Kumar"]
USER>do ##class(Sample.DAO.EmpeddedPY).DAOSet()
{"string":"Hello, world!","number_integer":42,"object":{"nested_key":"nested value"},"array":[1,"two",true,null,{"key":"changed to hello"}]}
Important Note: When using %Set(key, value) to modify a property, the value is computed as a runtime ObjectScript expression, and the result of that computation becomes the property's value.
Method Chaining
Such methods as %Set() and %Push() return chainable references and can be called from anywhere in the chain.
USER>Set jstring = "[123]"
USER>Write [].%FromJSON(jstring).%Set(1,"one").%Push("two").%Push("three").%Set(1,"final value").%ToJSON()
[123,"final value","two","three"]
%Push(Value, Type)
The %Push instance method appends the given value to the end of the current array, increasing its length.
This method has two formal parameters:
- Value (required): The actual value to be inserted at the end of the array. This value can be a JSON string, number, Boolean, or JSON object. Type (optional): This parameter helps enforce correct JSON data types during assignment. It is particularly critical when dealing with Booleans, nulls, large strings, or stream objects. You can refer to this type in the %Set() section.
USER>Set da = ##class(%DynamicArray).%New()
USER>Do da.%Push("test")
USER>Do da.%Push("","null")
USER>Do da.%Push(1,"Boolean")
USER>Do da.%Push("Test","string>Base64")
USER>Do da.%ToJSON()
["test",null,true,"VGVzdA=="]
%Remove(Key)
The %Remove method is used to delete an element from a JSON object or array. It returns the value of the removed element.
- When working with objects, pass the key to the element to remove.
- When working with arrays, pass the index of the element to remove.
Object
USER>Set json = {"username":"Test", "role":"Admin"}
USER>Write json.%Remove("username")
Test
USER>Write json.%ToJSON()
json={"role":"Admin"}
Array
USER>Set array = [1,2,3,4,5]
USER>Write array.%Remove(2)
3
USER>Write array.%ToJSON()
array=[1,2,4,5]
Embedded Python
Embedded Python - remove(key)
The Python remove function deletes the specified key from a DynamicObject or removes the element at the given index from a DynamicArray.
Class Sample.DAO.EmpeddedPY Extends %RegisteredObject
{
ClassMethod DAOremovePY(dao, key) [ Language = python ]
{
dao._Remove(key) #invoke IRIS DynamicObject %Remove method
dao.remove(key) #native Python method
}
ClassMethod DAORemove()
{
Set json = ##class(%DynamicObject).%New()
Set json."m_username"=$USERNAME
Set json.roles=$ROLES
Do ..DAOremovePY(json,"m_username")
ZWrite json
Set array = [1,"test",2,"test2"]
Do ..DAOremovePY(array,2)
ZWrite array
}
ClassMethod Sample2() [ Language = python ]
{
da = iris.cls("%Library.DynamicArray")._New()
da.put(0,3)
da.put(1,4)
da.remove(1)
da.remove(2)
print(da.size())
}
}
Output
USER>DO ##CLASS(Sample.DAO.EmpeddedPY). DAORemove()
json={"roles":"All"} ; <DYNAMIC OBJECT>
array=[1,"test","test2"] ; <DYNAMIC ARRAY>
This method is helpful when you need to clean up or selectively modify JSON structures during processing.
%Size()
The %Size() method returns the number of elements contained within a JSON object or array.
USER>Set json ={"username":($USERNAME),"role":($ROLES)}
USER>Write json.%Size()
2
USER>Set array = [1,2,3,4,5,6,7,9,0,121,"test"]
USER>Write array.%Size()
11
Embedded Python - size()
The Python size function returns the number of elements in a DynamicObject or DynamicArray
ClassMethod Size() [ Language = python ]
{
import iris
dao = iris.cls("%Library.DynamicObject")._New()
#
dao1 = iris.cls("%Library.DynamicObject")._New()
dao1._Set("key1","AAA")
dao1._Set("key2","AAA")
#
dao._Set("key1",dao1)
dao._Set("key2",dao1)
dao.put("key3",111)
dao.put("key4","test")
#Native Python size() function
print(dao.size()) # output 4
#IRIS DynamicArray %Size() method
print(dao.get("key1")._Size()) # output 2
}
The remaining methods will be discussed in the following article.