﻿ Replace elements in \$lb | InterSystems Developer Community | Beginner|Caché

# Replace elements in \$lb

## Primary tabs

Beginner, Caché

Let's say I have a list structure:

`set list = \$lb("stri,ng", \$c(0), 2)`

I want to replace all \$c(0) elements with empty elements, so my list would look like:

`set list = \$lb("stri,ng", , 2)`

What's the fastest way to do that?

I don't know the fastest way. I know a way:

`````` set list = \$lb("stri,ng", \$c(0), 2)
set list2 = "", ptr = 0
while \$listnext(list, ptr, elem) {
if elem'=\$C(0) {
set list2 = list2 _ \$LB(elem)
} else {
set list2 = list2 _ \$LB()
}
}
``````

I think best way is to use \$li to replace the item.

Then you need to set "list" again.

There's documentation on thia.

set list = \$lb("stri,ng", \$c(0), 2)
,p=0
for  set p=\$LISTFIND(list,\$C(0),p) quit:'p  set \$LIST(list,p)=""

Thanks, Robert.

It works fast, but replaces \$c(0) with empty string instead of empty element.

Can \$list replace replace \$c(0) with empty element?

Speed comparison:

``````Class POI.Test
{

/// do ##class(POI.Test).main()
ClassMethod main(rounds As %Integer = 1000, size As %Integer = 10, nullPercent As %Integer = 20)
{
set list = ..getList(size, nullPercent)

write !,"Rounds: ", rounds
write !,"Size: ", size
write !,"NullPercent: ", nullPercent
write !,"List: "
zwrite list

set ways = \$lb("listnext", "listfind", "lfs", "base")
for i=1:1:\$ll(ways) {
set way = \$lg(ways, i)
set start = \$zh

set list2 = \$classmethod(,way, rounds, list)

set end = \$zh

set time = end - start

write !,"Way: ", way
write !,"Time: ", time
write !,"List: "
zwrite list2
write !
}
}

ClassMethod base(rounds As %Integer = 1000, list As %List) As %List
{
for i=1:1:rounds {
set origList = list
}
quit origList
}

ClassMethod listfind(rounds As %Integer = 1000, list As %List)
{
for i=1:1:rounds {
set origList = list
set ptr=0
for  set ptr=\$LISTFIND(origList, \$c(0), ptr) quit:'ptr  set \$LIST(origList, ptr, ptr)=\$lb()
}
quit origList
}

ClassMethod listnext(rounds As %Integer = 1000, list As %List)
{
for i=1:1:rounds {
set list2 = ""
set ptr = 0
while \$listnext(list, ptr, elem) {
if elem'=\$C(0) {
set list2 = list2 _ \$LB(elem)
} else {
set list2 = list2 _ \$LB()
}
}
}
quit list2
}

ClassMethod lfs(rounds As %Integer = 1000, list As %List)
{
for i=1:1:rounds {
set str = \$lts(list)
set str = \$tr(str, \$c(0))
set list2 = \$lfs(str)
}
quit list2
}

ClassMethod getList(size As %Integer = 10, nullPercent As %Integer = 20) As %List
{
set list = ""
for i=1:1:size {
set list = list _ \$lb(\$select(\$random(101)<=nullPercent:\$c(0),1:\$random(50)))
}
quit list
}``````

Results:

```POI>do ##class(POI.Test).main(1000000)

Rounds: 1000000
Size: 10
NullPercent: 20
List: list=\$lb(25,20,\$c(0),\$c(0),4,42,\$c(0),28,44,3)

Way: listnext
Time: .944814
List: list2=\$lb(25,20,,,4,42,,28,44,3)

Way: listfind
Time: .610244
List: list2=\$lb(25,20,,,4,42,,28,44,3)

Way: lfs
Time: .430088
List: list2=\$lb("25","20","","","4","42","","28","44","3")

Way: base
Time: .032151
List: list2=\$lb(25,20,\$c(0),\$c(0),4,42,\$c(0),28,44,3)```

listfind solution seems optimal.

Ed, it's not about speed, but about syntax sugar on "for cycles". you can go like that:

```
```/// do ##class(POI.Test).main()
ClassMethod main(rounds As %Integer = 1000, size As %Integer = 10, nullPercent As %Integer = 20) {
set list = ..getList(size, nullPercent)
write !,"Rounds: ", rounds
write !,"Size: ", size
write !,"NullPercent: ", nullPercent
write !,"List: "
zwrite list
for way="listnext", "listfind", "lfs", "base" {

set start = \$zh set list2 = \$classmethod(,way, rounds, list)

set end = \$zh set time = end - start
write !,"Way: ", way
write !,"Time: ", time
write !,"List: "
zwrite list2

write ! }``````

Elaborated ;) Full classmethod Main() now.

You can get rid of two lines:

`set ways = \$lb("listnext", "listfind", "lfs", "base")`

and

`set way = \$lg(ways, i)`

if you change for to:

`for way="listnext", "listfind", "lfs", "base" {`

Do not forget that \$lb is just a list, concatenated list of single \$lb, and \$lb is a string in binary format.. So, just \$replace, will work

```USER>set list = \$lb("stri,ng", \$c(0), 2)

USER>set list = \$replace(list, \$lb(\$c(0)), \$lb())

USER>zw list
list=\$lb("stri,ng",,2)```

Unless you have list with \$c(3,1,0) as element

``````USER>set list = \$lb("stri,ng", \$c(0), 2, \$c(3,1,0), 3)

USER>set list = \$replace(list, \$lb(\$c(0)), \$lb())

USER>zw list
list=\$c(9,1)_"stri,ng"_\$c(1,3,4,2,5,1,1,3,4,3)

USER>w \$LL(list)

W \$LL(list)
^
<LIST>
``````

Here's a somewhat contrived case where that technique fails:

```USER>s weirdlist=\$lb("Very "_\$lb(\$c(0))_" odd data",\$c(0),2)

USER>s replaced=\$replace(weirdlist,\$lb(\$c(0)),\$lb())

USER>zw weirdlist
weirdlist=\$lb("Very "_\$c(3,1,0)_" odd data",\$c(0),2)

USER>zw replaced
replaced=\$c(19,1)_"Very "_\$c(1)_" odd data"_\$c(1,3,4,2)

USER>```