Written by

Developer - Internal Applications at InterSystems
Article Pravin Barton · May 1, 2020 1m read

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

Julius Kavay · May 2, 2020

In case, you want some speed, use

set outArray = []

instead of 

set outArray = ##class(%DynamicArray).%New()

Your speed gain: ca. 50%

0
Ashok Kumar T  Nov 4 to Julius Kavay

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()?

0
Julius Kavay  Nov 4 to Ashok Kumar T

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...

0
Vitaliy Serdtsev  Nov 5 to Ashok Kumar T

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()
There was a similar topic: Shared code execution speed
0