Written by

Senior Applications Developer at InterSystems
Question Preedhi Garg · Feb 13

How to append to a list in a for loop using ObjectScript

I want to append items to the list inside a for loop

Example:

set mylist = $ListBuild()
for i = 1:1:5 {
    set item = "item"_i
    set mylist = $ListBuild(mylist,item)
}

zw mylist

The output should be:

mylist = $lb("item1", "item2", "item3", "itme4", "item5")

The code snippet written above is not working, looking for correct way to do it.

Product version: IRIS 2024.3

Comments

Pravin Barton · Feb 13

Try the following:

set mylist = ""for i = 1:1:5 {
    set item = "item"_i
    set mylist = mylist _ $ListBuild(item)
}

zw mylist

$Listbuild lists have a separator that includes the length of the data in the next item of the list. This is why your original code wasn't working - $listbuild(mylist, item) would make a new list with two elements where the first item was the original list.

0
Timothy Leavitt  Feb 13 to Pravin Barton

This is close - just want to start with mylist = "" otherwise you have an empty list item at the beginning

0
Hannah Sullivan · Feb 13

Hi Preedhi,

You could use $ListUpdate to update your list in the for loop as follows.

set mylist = $ListBuild()
for i = 1:1:5 {
    set item = "item"_i
    set mylist = $ListUpdate(mylist,i,item)
}

zw mylist

This returns

USER>zw mylist
mylist=$lb("item1","item2","item3","item4","item5")
0
Jean Millette · Feb 13

Try concatenating the new item as follows:

set mylist = ""for i = 1:1:5 {
    set item = "item"_i
    set mylist = mylist_$ListBuild(item)
}

The output is:

zw mylist
mylist=$lb("item1","item2","item3","item4","item5")
0
Robert Cemper · Feb 13

2 options:

set mylist = ""for i = 1:1:5 {
    set item = "item"_i
    set mylist = mylist_$ListBuild(item)
}
zw mylist
kill mylist
for i = 1:1:5set$li(mylist,i)="item"_i
zw mylist
0
Brett Saviano · Feb 13

Of the three options presented already, concatenating with $LISTBUILD() is by far the most performant. Running the following method

ClassMethod ListTest(l = 100000)
{
    #; Concatenate with $LISTBUILDSet li="",zh=$ZHOROLOGFor i=1:1:lSet li=li_$LISTBUILD(i)
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LISTBUILD() took ",$ZHOROLOG-zh," seconds",!
    #; Set $LISTSet li="",zh=$ZHOROLOGFor i=1:1:lSet$LIST(li,i)=i
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LIST() took ",$ZHOROLOG-zh," seconds",!
    #; $LISTUPDATESet li="",zh=$ZHOROLOGFor i=1:1:lSet li=$LISTUPDATE(li,i,i)
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LISTUPDATE took ",$ZHOROLOG-zh," seconds"
}

on a recent version of IRIS produces these results:

USER>d##class(User.Test).ListTest()
Creating a list with length of 100000 using $LISTBUILD() took .007244 seconds
Creating a list with length of 100000 using $LIST() took 10.156168 seconds
Creating a list with length of 100000 using $LISTUPDATE took 10.954107 seconds
0
Joel Solon · Mar 12

...and it makes sense that using $listbuild to add at the end would be better than the other two options, which are general purpose ("find the position in the list and put something there").

0
Steven Hobbs · Mar 12

Interestingly, for small examples, L<30, the first example is slower because it does both a $LISTBUILD plus a concatenation while the others just call a $LIST/$LISTUPDATE built-in.  But for large examples, L>1000, the first example can win by at least one order of magnitude because the other examples include execution steps that take O(L**2) time.

0
Steven Hobbs  Mar 12 to Steven Hobbs

An aside: when you have two $LIST values, L1 and L2 ,that you want to concatenate then you can just compute L1_L2 and string concatenation will do the job.  Some programmers loop over L2 one element at at time and add that element to the end of L1.  This can take n-squared time based on some product of the $LISTLENGTHs of L1 and L2.  Using string concatenation just depends on the sum on the lengths of L1 and L2.

0
Vitaliy Serdtsev · Mar 13

Another solution via $LISTFROMSTRING:

<FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">s</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"item1"
</FONT><FONT COLOR="#0000ff">for </FONT><FONT COLOR="#808000">i</FONT><FONT COLOR="#000000">=2:1:5 </FONT><FONT COLOR="#800080">{
  </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">s</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#808000">s</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#008000">",item"</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#808000">i
</FONT><FONT COLOR="#800080">}
</FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">mylist</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$listfromstring</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">s</FONT><FONT COLOR="#000000">)
</FONT><FONT COLOR="#0000ff">zwrite </FONT><FONT COLOR="#808000">mylist </FONT><FONT COLOR="#008000">; mylist = $lb("item1","item2","item3","item4","item5")</FONT>
0