It depends on a use case.

  • For access by position use $lb.
  • For access by key use locals.

Consider the scenario of iterating over the result set. You need to do two things:

  • Convert value based on a column datatype
  • If a value is special translate it

To solve the first one (and assuming we get values by position number) the most efficient solution would be iterating over metadata once and building something like this:

set columns = $lb("int", "bool", "str", ...)

Then in each row we can easily get datatype by:

for i=1:1:colCount {
  set dataType = $lg(columns, i)
  set value = rs.Get(i)
}

Now for a second part - value translation, locals are great here. We prep our translator:

set local(1) = "a"
set local("hi") = "world"

and replace the value if needed

set:$data(local(value), newValue) value = newValue

Ok.

Parameter is about 6x faster btw:

ClassMethod GetMonthList1() As %List
{
    Quit $Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}

ClassMethod GetMonthList2() As %List [ CodeMode = expression ]
{
$Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}

ClassMethod GetMonthList3() As %List [ CodeMode = expression ]
{
$lb("January","February","March","April","May","June","July","August","September","October","November","December")
}

Parameter GetMonthList = {$lb("January","February","March","April","May","June","July","August","September","October","November","December")};

ClassMethod Time2()
{
    for method = 1:1:3 {
        set start = $zh
        
        for i=1:1:10000 {
            set result = $classmethod(,"GetMonthList" _ method)
        }
        
        set end = $zh
        
        write $$$FormatText("Method: %1, time: %2", "GetMonthList" _ method, end - start),!
        
    }
    
    set start = $zh
    
    for i=1:1:10000 {
        set result = ..#GetMonthList
    }
    
    set end = $zh
    
    write $$$FormatText("Parameter, time: %1",  end - start),!
}

Results

Method: GetMonthList1, time: .007255
Method: GetMonthList2, time: .006717
Method: GetMonthList3, time: .003878
Parameter, time: .000605

Why

ClassMethod GetMonthList1() As %List
{
    Quit $Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}

instead of

ClassMethod GetMonthList3() As %List
{
 Quit $lb("January","February","March","April","May","June","July","August","September","October","November","December")
}
  • pCaption -  return localized caption which would be shown above results
  • pResults  - all results go here
  • pTopResults  - copy some of the results here to show them on top
  • pParms  - local array in which you can pass params
  • pSearchKey - no idea

For example

Parameter SETTINGS = "XSLТ:Basic:selector?context={isc.util.EnsSearchUtils/GetXDatas?class=util.XDatas}"

And inside the method you would get

zw pParms 

pParms("class") = "util.XDatas"

Here's sample code

ClassMethod GetXDatas(Output pCaption As %String, Output pTopResults, Output pResults, ByRef pParms As %String, pSearchKey As %String = "") As %Status
{
    Set tStatus = $$$OK
    Kill pResults, pTopResults
    Set pCaption = $$$Text("My Localized Caption")

    Set tClass = $get(pParms("class"))
    If tClass '= "" {
        Set tClassObj = ##class(%Dictionary.CompiledClass).%OpenId(tClass)

        For i=1:1:tClassObj.XDatas.Count() {
            Set tName = tClassObj.XDatas.GetAt(i).Name
            Set pResults($i(pResults)) = tName
            
            Set:tName["import" pTopResults($i(pTopResults)) = tName
        }
    }
    Quit tStatus
}

}

It would search for all XDatas in class parameter (utils.XDatas in our case) and show those of them containing Import word at the top. Caption would be "My Localized Caption" but you can add localizations to it.

You're right, I need to change $replace with Ш to $replace with Щ. Ш is replaced in $translate anyway

ClassMethod convertRussionToEnglish4(russian = "привет") As %String [ CodeMode = expression ]
{
$tr($zcvt($replace($replace($tr(russian, "абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭЖЦЧШЮЯжцчшюяьЬъЪ", "abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE婨味䍨卨奵奡穨瑳捨獨祵祡"),"щ","shch"),"Щ","Shch"),"O","UnicodeBig"),$c(0))
}

Here's my new one-liner. Now 6 times faster.

ClassMethod convertRussionToEnglish4(russian = "привет") As %String [ CodeMode = expression ]
{
$tr($zcvt($replace($replace($tr(russian, "абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭЖЦЧШЮЯжцчшюяьЬъЪ", "abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE婨味䍨卨奵奡穨瑳捨獨祵祡"),"щ","shch"),"Ш","Sh"),"O","UnicodeBig"),$c(0))
}

Here's tests:

do ##class(Test.Cyr).Time()
Method: convertRussionToEnglish1, time: .009022 <- original
Method: convertRussionToEnglish2, time: .000689 <- my first idea
Method: convertRussionToEnglish3, time: .000417 <- Evgeny
Method: convertRussionToEnglish4, time: .000072 <- this version
Method: convertRussionToEnglish5, time: .000124 <- Jon
 
Compete code

Less searching all around:

ClassMethod getDict(Output dict)
{
    kill dict
    set dict("а")="a"
    set dict("б")="b"
    set dict("в")="v"
    set dict("г")="g"
    set dict("д")="d"
    set dict("е")="e"
    set dict("ж")="zh"
    set dict("з")="z"
    set dict("и")="i"
    set dict("й")="y"
    set dict("к")="k"
    set dict("л")="l"
    set dict("м")="m"
    set dict("н")="n"
    set dict("о")="o"
    set dict("п")="p"
    set dict("р")="r"
    set dict("с")="s"
    set dict("т")="t"
    set dict("у")="u"
    set dict("ф")="f"
    set dict("х")="kh"
    set dict("ц")="ts"
    set dict("ч")="ch"
    set dict("ш")="sh"
    set dict("щ")="shch"
    set dict("ъ")=""
    set dict("ы")="y"
    set dict("ь")=""
    set dict("э")="e"
    set dict("ю")="yu"
    set dict("я")="ya"
}

/// w ##class(Test.Cyr).convertRussionToEnglish()
ClassMethod convertRussionToEnglish(word As %String = "Привет")
{
    do ..getDict(.dict)
    set out = ""
    for i=1:1:$l(word) {
        set letter = $e(word, i)
        set letterL = $zcvt(letter, "l")
        set outLetter = dict(letterL)
        set:letter'=letterL outLetter = $zcvt(outLetter, "U")
        set out = out _ outLetter
    }
    quit out
}