From iris-dev
Provides ObjectScript patterns for efficient list building with $LISTBUILD, iteration via $LISTNEXT, CSV conversion with $LISTTOSTRING, deduplication, and safe removal. Avoids O(n²) concatenation pitfalls.
npx claudepluginhub intersystems-community/iris-devThis skill uses the workspace's default tool permissions.
```objectscript
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
// WRONG — $LISTBUILD creates a new list each iteration, O(n²):
Set lst = ""
For i=1:1:count {
Set lst = lst _ $LISTBUILD(values.GetAt(i))
}
// CORRECT — accumulate into a %ListOfDataTypes, convert at end:
Set result = ##class(%ListOfDataTypes).%New()
For i=1:1:values.Count() {
Do result.Insert(values.GetAt(i))
}
// CORRECT — for CSV output specifically, use $LISTTOSTRING:
Set lst = ""
For i=1:1:values.Count() {
Set lst = lst _ $LISTBUILD(values.GetAt(i))
}
Set csv = $LISTTOSTRING(lst, ",")
The O(n²) string concat is always wrong for >10 items. Use $LISTBUILD accumulation then $LISTTOSTRING:
// O(n²) — WRONG for large lists:
Set result = ""
For i=1:1:values.Count() {
If (i > 1) { Set result = result _ "," }
Set result = result _ values.GetAt(i)
}
// O(n) — CORRECT:
Set lst = ""
For i=1:1:values.Count() {
Set lst = lst _ $LISTBUILD(values.GetAt(i))
}
Return $LISTTOSTRING(lst, ",")
// Preferred — no index arithmetic, handles empty list correctly:
Set ptr = 0
While $LISTNEXT(lst, ptr, val) {
// process val
}
// Alternative — $List is 1-based:
For i=1:1:$LISTLENGTH(lst) {
Set val = $List(lst, i)
// process val
}
// Note: $LISTLENGTH("") = 0 (truly empty), $LISTLENGTH($LISTBUILD()) = 1 (one empty element!)
// Use "" not $LISTBUILD() to represent an empty list
// WRONG — O(n²), calls Find() for every item:
For i=1:1:list2.Count() {
Set item = list2.GetAt(i)
If (result.Find(item) = "") {
Do result.Insert(item)
}
}
// CORRECT — O(n) with temp array as hash set:
Set seen = ""
For i=1:1:list1.Count() {
Set item = list1.GetAt(i)
Set seen(item) = ""
Do result.Insert(item)
}
For i=1:1:list2.Count() {
Set item = list2.GetAt(i)
If '$Data(seen(item)) {
Set seen(item) = ""
Do result.Insert(item)
}
}
Kill seen
// WRONG — removing during forward iteration skips items:
For i=1:1:items.Count() {
If (items.GetAt(i) [ "DELETE") { Do items.RemoveAt(i) }
}
// CORRECT — iterate backwards so indices stay valid:
For i=items.Count():-1:1 {
If (items.GetAt(i) [ "DELETE") { Do items.RemoveAt(i) }
}
Set csv = "a,b,c"
Set lst = $LISTFROMSTRING(csv, ",") // creates %List from delimited string
Set back = $LISTTOSTRING(lst, ",") // "a,b,c"
Set lst2 = $LISTBUILD("a", "b", "c") // creates %List from literal values
// %ListOfDataTypes: object wrapper, use Insert/GetAt/Count/Find/RemoveAt
Set lst = ##class(%ListOfDataTypes).%New()
Do lst.Insert("value")
Set val = lst.GetAt(1) // 1-based
Set n = lst.Count()
Set pos = lst.Find("value") // returns "" if not found, else position
// %List (raw): use $LISTBUILD/$LIST/$LISTLENGTH/$LISTNEXT
Set lst = $LISTBUILD("a","b")
Set val = $LIST(lst, 1) // 1-based
Set n = $LISTLENGTH(lst)