Code sample to concatenate JSON arrays
ObjectScript doesn't include any built-in method for appending one JSON dynamic array to another. Here's a code snippet I use that's equivalent to the JavaScript concat() method.
Call it with any number of arguments to concatenate them into a new array. If an argument is a dynamic array, its elements will be added. Otherwise the argument itself will be added.
ClassMethod ConcatArrays(pArgs...) As %DynamicArray
{
set outArray = ##class(%DynamicArray).%New()
for i=1:1:pArgs {
set arg = pArgs(i)
if ($IsObject(arg) && arg.%IsA("%DynamicArray")) {
set iter = arg.%GetIterator()
while iter.%GetNext(.key, .value) {
do outArray.%Push(value)
}
} else {
do outArray.%Push(arg)
}
}
return outArray
}
Feel free to let me know if there's a better way to do this!
Comments
In case, you want some speed, use
set outArray = []instead of
set outArray = ##class(%DynamicArray).%New()Your speed gain: ca. 50%
Hi @Julius Kavay
The literal array syntax set outArray = [] internally creates a %DynamicArray object. If both approaches ultimately produce a %DynamicArray, why is using the literal syntax reportedly about 50% faster than explicitly calling set outArray = ##class(%DynamicArray).%New()?
Well, I'm neither part of the ObjectScript nor the Objects developer team, hence I can't answer the "why" part of your question but fact is, timing mesuremenst show a significat higher speeds for the literal versions:
ClassMethod DynObject()
{
while$zh#1 {} set t1=$zhfor i=1:1:1E6 { if##class(%DynamicArray).%New() } set t1=$zh-t1
while$zh#1 {} set t2=$zhfor i=1:1:1E6 { if##class(%DynamicObject).%New() } set t2=$zh-t2
while$zh#1 {} set t3=$zhfor i=1:1:1E6 { if [] } set t3=$zh-t3
while$zh#1 {} set t4=$zhfor i=1:1:1E6 { if {} } set t4=$zh-t4
write"Times for : Class Literal Diff",!
write"DynArray :", $j(t1,9,3), $j(t3,9,3), $j(t1/t3-1*100,9,2),"%",!
write"DynObject :", $j(t2,9,3), $j(t4,9,3), $j(t2/t4-1*100,9,2),"%",!
}
The output will depend on
- IRIS/Cache version in use and
- on the underlying hardware
My values are
USER>d##class(DC.Times).DynObject()
Times for : Class Literal Diff
DynArray : 0.6650.40165.90%
DynObject : 0.6490.40161.87%
Maybe someone else or the WRC has an explanation...
Thank you for the clarification @Julius Kavay
I would venture to assume that this difference is due to the overhead of calling the class method. In other words:
- ##class(%DynamicArray).%New() -> ..%OnNew() -> $ZU()
- [] -> $ZU()
Nice tip! I put it on GitHub.
https://gist.github.com/rajrsingh/18f63b05abf7cdaff31b414d860f2b44