Convert %ArrayOfDataTypes to array, and back again
Here's an easy one for you; before I spend another hour looking for the answer, how do you convert %ArrayOfDataTypes to an array (that could, say, fit into the %session.Data array, or maybe just some array named info()), and of course back again?
NS>s aodt=##class(%ArrayOfDataTypes).%New()
NS>w aodt.SetAt("lcavanaugh","username")
1
NS>w aodt.SetAt("organization","coolcompany")
1
NS>w ##class(%ArrayOfDataTypes).BuildValueArray(aodt,.array)
<LIST>zBuildValueArray+1^%Library.ArrayOfDataTypes.1
aodt must be serialzed. What?
NS>zw array
NS>
Comments
There isn't a built-in method that does exactly what you're looking for, that I know of. Here's a simple example of how to do it, though:
Class DC.Demo.ArrayUtils
{
ClassMethod ArrayObjectToArray(pSource As %Collection.AbstractArray, Output pTarget)
{
Kill pTarget
Set tKey = ""
For {
Set tItem = pSource.GetNext(.tKey)
Quit:tKey=""
Set pTarget(tKey) = tItem
}
}
ClassMethod ArrayToArrayObject(ByRef pSource, pTarget As %Collection.AbstractArray)
{
// Could initialize pTarget here and return it Output, or return it normally.
// This is just a bit more general because it'll work with any array collection type.
Do pTarget.Clear()
Set tKey = ""
For {
Set tKey = $Order(pSource(tKey),1,tItem)
Quit:tKey=""
Do pTarget.SetAt(tItem,tKey)
}
}
}
Usage:
USER>s aodt=##class(%ArrayOfDataTypes).%New()
USER>w aodt.SetAt("lcavanaugh","username")
1
USER>w aodt.SetAt("organization","coolcompany")
1
USER>zw aodt
aodt=<OBJECT REFERENCE>[1@%Library.ArrayOfDataTypes]
+----------------- general information ---------------
| oref value: 1
| class name: %Library.ArrayOfDataTypes
| reference count: 2
+----------------- attribute values ------------------
|Data("coolcompany") = "organization"
| Data("username") = "lcavanaugh"
| ElementType = "%String"
+-----------------------------------------------------
USER>do ##class(DC.Demo.ArrayUtils).ArrayObjectToArray(aodt,.array)
USER>zw array
array("coolcompany")="organization"
array("username")="lcavanaugh"
USER>s newaodt = ##class(%Library.ArrayOfDataTypes).%New()
USER>do ##class(DC.Demo.ArrayUtils).ArrayToArrayObject(.array,newaodt)
USER>zw newaodt
newaodt=<OBJECT REFERENCE>[2@%Library.ArrayOfDataTypes]
+----------------- general information ---------------
| oref value: 2
| class name: %Library.ArrayOfDataTypes
| reference count: 2
+----------------- attribute values ------------------
|Data("coolcompany") = "organization"
| Data("username") = "lcavanaugh"
| ElementType = "%String"
+-----------------------------------------------------If you really wanted to make BuildValueArray work:
USER>d aodt.%SerializeObject(.serial)
USER>d aodt.BuildValueArray($lg(serial),.anotherarray)
USER>zw anotherarray
anotherarray("coolcompany")="organization"
anotherarray("username")="lcavanaugh"The utility method approach would probably at least be clearer. ![]()
Ooh, fun, thanks. Can I use it with %ListOfDataTypes too? I have both returned from methods, and I need to use them in the %session array.
ArrayObjectToArray happens to also work with %ListOfDataTypes, but ArrayToArrayObject won't as written, because %Library.ListOfDataTypes:SetAt only allows changing existing keys. You could write a similar method for lists that uses Insert() rather than SetAt().