T4.2: Manipulates Lists

Knowledge Review - InterSystems ObjectScript Specialist

1. $LIST/$LISTBUILD para insertar, actualizar y eliminar elementos de listas

Puntos Clave

  • $LISTBUILD($LB): Crea una lista a partir de valores separados por comas: $LB("Alice", 30, "NY")
  • $LIST para lectura: $LIST(list, position) extrae el elemento en la posición (base 1)
  • $LIST para escritura: SET $LIST(list, position) = value reemplaza un elemento
  • Rango $LIST: $LIST(list, from, to) extrae una sublista
  • Elementos indefinidos: $LB("a",,"c") crea una lista con un segundo elemento indefinido
  • Agregar al final: SET $LIST(list, *+1) = value agrega al final de una lista
  • Eliminar: SET $LIST(list, position) = "" establece como vacío; use concatenación de sublistas para eliminar verdaderamente

Notas Detalladas

Descripción general

Las listas en ObjectScript son estructuras binarias codificadas (no cadenas delimitadas). Se crean con $LISTBUILD (abreviado $LB) y se manipulan con $LIST (abreviado $LI). Las listas preservan los tipos de datos internamente y pueden contener cadenas, números y elementos indefinidos.

Creación de listas con $LISTBUILD

 // Create a simple list
 SET myList = $LISTBUILD("Alice", 30, "New York")

 // Shorthand $LB
 SET colors = $LB("Red", "Green", "Blue")

 // List with undefined element (note the double comma)
 SET sparse = $LB("first",, "third")

 // Empty list
 SET empty = $LB()

 // Single element
 SET single = $LB("only")

Lectura de elementos de lista con $LIST

 SET person = $LB("Alice", 30, "New York")

 // Extract individual elements (1-based indexing)
 WRITE $LIST(person, 1), !    // Alice
 WRITE $LIST(person, 2), !    // 30
 WRITE $LIST(person, 3), !    // New York

 // $LI shorthand
 WRITE $LI(person, 1), !      // Alice

 // Extract a sublist (from position 2 to 3)
 SET subset = $LIST(person, 2, 3)
 // subset is $LB(30, "New York")

 // Extract from position to end
 SET fromSecond = $LIST(person, 2, *)
 // fromSecond is $LB(30, "New York")

Modificación de elementos de lista con SET $LIST

 SET person = $LB("Alice", 30, "New York")

 // Update an element
 SET $LIST(person, 2) = 31
 // person is now $LB("Alice", 31, "New York")

 // Append to the end using *+1
 SET $LIST(person, *+1) = "alice@example.com"
 // person is now $LB("Alice", 31, "New York", "alice@example.com")

 // Replace first element
 SET $LIST(person, 1) = "Bob"

Eliminación de elementos

No existe una operación de eliminación directa. Para eliminar un elemento, se concatenan sublistas excluyendo el elemento no deseado:

 SET list = $LB("A", "B", "C", "D", "E")

 // Remove element at position 3 ("C")
 SET list = $LIST(list, 1, 2) _ $LIST(list, 4, *)
 // Result: $LB("A", "B", "D", "E")

 // Remove first element
 SET list = $LIST(list, 2, *)
 // Result: $LB("B", "D", "E")

 // Remove last element
 SET list = $LIST(list, 1, *-1)
 // Result: $LB("B", "D")

Construcción incremental de listas

 SET list = ""
 FOR i = 1:1:5 {
     SET list = list _ $LB(i * 10)
 }
 // list is $LB(10, 20, 30, 40, 50)

Referencias de Documentación

2. $LISTGET y $LISTNEXT para recuperación

Puntos Clave

  • $LISTGET($LG): Recuperación segura -- devuelve un valor predeterminado si el elemento es indefinido o falta
  • $LG(list, position, default): Tres argumentos: lista, posición, valor predeterminado
  • $LISTNEXT: Itera a través de una lista usando una variable puntero -- más eficiente para acceso secuencial
  • $LISTNEXT(list, pointer, value): Actualiza puntero y valor en cada llamada, devuelve 1 mientras quedan elementos
  • Inicialización del puntero: Siempre establezca el puntero en 0 antes de iniciar la iteración con $LISTNEXT
  • Rendimiento: $LISTNEXT es más rápido que $LIST para recorrido secuencial de listas largas

Notas Detalladas

Descripción general

$LISTGET proporciona acceso seguro a elementos de lista con valores predeterminados para elementos faltantes o indefinidos. $LISTNEXT proporciona iteración secuencial eficiente a través de listas. Juntas, estas funciones manejan los patrones de acceso a listas más comunes.

$LISTGET para acceso seguro

 SET person = $LB("Alice", 30, "New York")

 // Basic retrieval with default
 WRITE $LISTGET(person, 1, "Unknown"), !     // Alice
 WRITE $LISTGET(person, 4, "N/A"), !         // N/A (position 4 doesn't exist)

 // $LG shorthand
 WRITE $LG(person, 2, 0), !                  // 30
 WRITE $LG(person, 99, "default"), !          // default

 // With sparse lists (undefined elements)
 SET sparse = $LB("first",, "third")
 WRITE $LG(sparse, 2, "MISSING"), !           // MISSING (element 2 is undefined)

 // Without default, $LG returns "" for missing elements
 WRITE $LG(person, 10), !                     // "" (empty string)

$LISTGET vs $LIST

 SET list = $LB("A",, "C")

 // $LIST throws an error on undefined element
 // WRITE $LIST(list, 2)  // <NULL VALUE> error!

 // $LISTGET returns default safely
 WRITE $LISTGET(list, 2, "default"), !    // default

 // $LIST also errors on out-of-range position
 // WRITE $LIST(list, 10)  // <NULL VALUE> error!

 // $LISTGET handles it gracefully
 WRITE $LISTGET(list, 10, "N/A"), !       // N/A

$LISTNEXT para iteración secuencial

 SET colors = $LB("Red", "Green", "Blue", "Yellow")

 // Initialize pointer to 0
 SET ptr = 0
 WHILE $LISTNEXT(colors, ptr, value) {
     WRITE "Color: ", value, !
 }
 // Output: Red, Green, Blue, Yellow (one per line)

$LISTNEXT con listas dispersas

 SET data = $LB("first",, "third",, "fifth")

 SET ptr = 0
 SET pos = 0
 WHILE $LISTNEXT(data, ptr, value) {
     SET pos = pos + 1
     IF $DATA(value) {
         WRITE "Position ", pos, ": ", value, !
     } ELSE {
         WRITE "Position ", pos, ": <undefined>", !
     }
 }
 // Output:
 //   Position 1: first
 //   Position 2: <undefined>
 //   Position 3: third
 //   Position 4: <undefined>
 //   Position 5: fifth

Comparación de rendimiento

Para listas grandes, $LISTNEXT es significativamente más rápido porque mantiene un puntero interno y lee secuencialmente. $LIST(list, n) debe escanear desde el inicio cada vez para encontrar la posición n.

 // Building a large list
 SET bigList = ""
 FOR i = 1:1:10000 {
     SET bigList = bigList _ $LB(i)
 }

 // SLOW: $LIST with index (O(n^2) overall)
 FOR i = 1:1:$LISTLENGTH(bigList) {
     SET val = $LIST(bigList, i)
 }

 // FAST: $LISTNEXT with pointer (O(n) overall)
 SET ptr = 0
 WHILE $LISTNEXT(bigList, ptr, val) {
     // process val
 }

Referencias de Documentación

3. Conversión de listas a/desde cadenas

Puntos Clave

  • $LISTTOSTRING: Convierte una lista a cadena delimitada: $LISTTOSTRING(list, delimiter)
  • $LISTFROMSTRING: Convierte una cadena delimitada a lista: $LISTFROMSTRING(string, delimiter)
  • Delimitador predeterminado: La coma es el delimitador predeterminado para ambas funciones
  • $LISTLENGTH($LL): Devuelve el número de elementos en una lista
  • $LISTVALID: Verifica si un valor es una lista válida (devuelve 1 o 0)
  • Listas vs cadenas: Las listas preservan tipos de datos y soportan elementos indefinidos; las cadenas no

Notas Detalladas

Descripción general

ObjectScript proporciona funciones para convertir entre su formato nativo de lista (creado por $LISTBUILD) y cadenas delimitadas. Esto es esencial al interactuar con sistemas externos, mostrar datos o procesar archivos de entrada delimitados.

$LISTTOSTRING: Lista a cadena delimitada

 SET colors = $LB("Red", "Green", "Blue")

 // Default delimiter is comma
 WRITE $LISTTOSTRING(colors), !
 // Output: Red,Green,Blue

 // Custom delimiter
 WRITE $LISTTOSTRING(colors, "|"), !
 // Output: Red|Green|Blue

 // Tab-delimited
 WRITE $LISTTOSTRING(colors, $CHAR(9)), !
 // Output: Red<tab>Green<tab>Blue

 // With numeric elements
 SET nums = $LB(10, 20, 30)
 WRITE $LISTTOSTRING(nums, "-"), !
 // Output: 10-20-30

$LISTFROMSTRING: Cadena delimitada a lista

 SET csv = "Alice,30,New York"

 // Default delimiter is comma
 SET list = $LISTFROMSTRING(csv)
 WRITE $LIST(list, 1), !    // Alice
 WRITE $LIST(list, 2), !    // 30
 WRITE $LIST(list, 3), !    // New York

 // Custom delimiter
 SET piped = "Red|Green|Blue"
 SET colors = $LISTFROMSTRING(piped, "|")
 WRITE $LIST(colors, 2), !  // Green

 // Note: all elements become STRINGS
 // "30" from CSV is stored as string "30", not integer 30

$LISTLENGTH: Conteo de elementos

 SET colors = $LB("Red", "Green", "Blue")
 WRITE $LISTLENGTH(colors), !    // 3

 // $LL shorthand
 WRITE $LL(colors), !             // 3

 // Sparse list -- undefined elements count
 SET sparse = $LB("a",, "c")
 WRITE $LL(sparse), !             // 3

 // Empty list
 WRITE $LL($LB()), !              // 0

$LISTVALID: Validación de formato de lista

 SET list = $LB("a", "b", "c")
 WRITE $LISTVALID(list), !        // 1

 SET str = "a,b,c"
 WRITE $LISTVALID(str), !         // 0

 SET empty = ""
 WRITE $LISTVALID(empty), !       // 1 (empty string is valid empty list)

Patrones prácticos de conversión

 // Read CSV line and convert to list for processing
 SET csvLine = "John,Smith,42,Engineer"
 SET fields = $LISTFROMSTRING(csvLine, ",")
 SET firstName = $LG(fields, 1)
 SET lastName = $LG(fields, 2)
 SET age = $LG(fields, 3)

 // Build a list and output as pipe-delimited
 SET output = $LB(firstName, lastName, age + 1)
 WRITE $LISTTOSTRING(output, "|"), !
 // Output: John|Smith|43

 // Counting items in a delimited string via list conversion
 SET tags = "iris,objectscript,sql,globals"
 WRITE "Number of tags: ", $LL($LISTFROMSTRING(tags, ",")), !
 // Output: Number of tags: 4

$LISTFIND: Búsqueda dentro de listas

 SET colors = $LB("Red", "Green", "Blue", "Yellow")

 // Find position of "Blue"
 WRITE $LISTFIND(colors, "Blue"), !     // 3

 // Not found returns 0
 WRITE $LISTFIND(colors, "Purple"), !   // 0

 // Case-sensitive
 WRITE $LISTFIND(colors, "red"), !      // 0

Resumen de Preparación para el Examen

Conceptos críticos a dominar:

  1. $LISTBUILD crea listas binarias: No son lo mismo que cadenas delimitadas -- son estructuras codificadas
  2. Indexación base 1: Las posiciones de lista comienzan en 1, no en 0
  3. $LIST vs $LISTGET: $LIST genera error en elementos indefinidos/faltantes; $LISTGET devuelve un valor predeterminado de forma segura
  4. Eficiencia de $LISTNEXT: Acceso secuencial O(n) vs O(n^2) para $LIST indexado en un bucle
  5. Puntero de $LISTNEXT: Debe inicializarse a 0 antes de la iteración
  6. Elementos indefinidos: $LB("a",,"c") tiene un segundo elemento indefinido -- $LIST genera error, $LISTGET devuelve el predeterminado
  7. $LISTTOSTRING/$LISTFROMSTRING: Convierten entre formatos de lista y cadena delimitada
  8. $LISTLENGTH: Cuenta TODOS los elementos incluyendo los indefinidos
  9. Agregar al final: Use `_ $LB(newVal)` para concatenación o `SET $LIST(list, *+1) = val`

Escenarios comunes de examen:

  • Elegir entre $LIST y $LISTGET para recuperación segura
  • Escribir un bucle $LISTNEXT para procesar todos los elementos
  • Convertir entre cadenas CSV y listas $LISTBUILD
  • Manejar elementos indefinidos en listas dispersas
  • Determinar la salida de $LISTLENGTH en listas dispersas
  • Eliminar un elemento de una lista mediante concatenación de sublistas
  • Usar $LISTFIND para buscar un valor en una lista

Recomendaciones de práctica:

  • Crear listas con $LISTBUILD y extraer elementos con $LIST y $LISTGET
  • Experimentar con listas dispersas y observar el comportamiento de error con $LIST vs $LISTGET
  • Escribir bucles $LISTNEXT y comparar con bucles $LIST indexados
  • Convertir cadenas delimitadas a listas y viceversa
  • Practicar agregar y eliminar elementos de listas
  • Usar $LISTVALID para probar varios valores en cuanto a validez de lista
  • Construir una utilidad que lea datos CSV, convierta a listas y procese cada registro

Report an Issue