📝

Funciones de Lista (List.*)

Las listas son colecciones ordenadas de valores en M. Son fundamentales porque aparecen constantemente como parámetros y resultados en las funciones de tabla. Dominar List.* es dominar M.

Intermedio

Agregación de Listas

List.Sum

Intermedio

Sintaxis

List.Sum(lista as list, optional precision as nullable number) as any

¿Qué hace?

Suma todos los valores numéricos de una lista. Si la lista está vacía, devuelve 0. Si contiene null, los ignora.

Ejemplo

List.Sum({1, 2, 3, 4, 5})          // → 15
List.Sum({10, null, 20, null})     // → 30  (ignora nulls)
List.Sum({})                       // → 0

// Uso típico: sumar una columna de tabla
List.Sum(Tabla[Importe])           // suma todos los valores de la columna Importe

List.Average

Intermedio

Sintaxis

List.Average(lista as list, optional precision as nullable number) as any

¿Qué hace?

Calcula la media aritmética de los valores de una lista, ignorando los nulls. Devuelve null si la lista está vacía o solo tiene nulls.

Ejemplo

List.Average({10, 20, 30})         // → 20
List.Average({10, null, 30})       // → 20  (ignora el null)
List.Average({})                   // → null

List.Count

Intermedio

Sintaxis

List.Count(lista as list) as number

¿Qué hace?

Cuenta el número total de elementos de una lista, incluyendo los nulls.

Ejemplo

List.Count({1, 2, 3})              // → 3
List.Count({1, null, 3})           // → 3  (cuenta el null)
List.Count({})                     // → 0

List.Min / List.Max

Intermedio

Sintaxis

List.Min(lista as list, optional default as any, optional comparer as nullable function) as any
List.Max(lista as list, optional default as any, optional comparer as nullable function) as any

¿Qué hace?

Devuelve el valor mínimo o máximo de la lista. El parámetro default se devuelve si la lista está vacía.

Ejemplo

List.Min({3, 1, 4, 1, 5})         // → 1
List.Max({3, 1, 4, 1, 5})         // → 5
List.Min({}, 0)                    // → 0  (valor por defecto si lista vacía)

// Útil para obtener la fecha más antigua de una columna
List.Min(Tabla[Fecha])             // → fecha mínima
🔍

Filtrar y Buscar

List.Distinct

Intermedio

Sintaxis

List.Distinct(lista as list, optional comparer as nullable function) as list

¿Qué hace?

Devuelve la lista sin duplicados, manteniendo el orden de primera aparición.

Ejemplo

List.Distinct({1, 2, 2, 3, 1})         // → {1, 2, 3}
List.Distinct({"A", "b", "A", "B"},
    Comparer.OrdinalIgnoreCase)         // → {"A", "b"}  (ignora mayúsculas)

List.Contains

Intermedio

Sintaxis

List.Contains(lista as list, valor as any, optional comparer as nullable function) as logical

¿Qué hace?

Comprueba si un valor está en la lista. Devuelve true o false. Muy útil en filtros de tabla.

Ejemplo: Filtrar por lista de valores

List.Contains({1, 2, 3}, 2)            // → true
List.Contains({"A", "B"}, "C")         // → false

// Patrón clásico: filtrar tabla por lista de países
let
    PaisesPermitidos = {"España", "Francia", "Italia"},
    Filtrado = Table.SelectRows(
        Ventas,
        each List.Contains(PaisesPermitidos, [Pais])
    )
in
    Filtrado
💡 Tip kawaii: List.ContainsAll comprueba si todos los valores están en la lista, y List.ContainsAny si alguno está.

List.First / List.Last

Intermedio

Sintaxis

List.First(lista as list, optional default as any) as any
List.Last(lista as list, optional default as any) as any

¿Qué hace?

Devuelve el primer o último elemento de la lista. Muy útil combinado con Table.SelectRows para hacer lookups de un único valor.

Ejemplo: Lookup de valor único

// Obtener el nombre del cliente con ID 42
List.First(
    Table.SelectRows(Clientes, each [ID] = 42)[Nombre],
    "Sin nombre"   // valor por defecto si no encuentra nada
)

List.Select

Intermedio

Sintaxis

List.Select(lista as list, condicion as function) as list

¿Qué hace?

Filtra los elementos de una lista manteniendo solo los que cumplen la condición. Es el equivalente de Table.SelectRows pero para listas.

Ejemplo

List.Select({1, 2, 3, 4, 5, 6}, each _ > 3)     // → {4, 5, 6}
List.Select({"Ana", "", "Luis", null}, each _ <> null and _ <> "")  // → {"Ana", "Luis"}
🔄

Transformar Listas

List.Transform

Intermedio

Sintaxis

List.Transform(lista as list, funcion as function) as list

¿Qué hace?

Aplica una función a cada elemento de la lista y devuelve una nueva lista con los resultados. Es el map de M.

Ejemplo

// Doblar cada número
List.Transform({1, 2, 3, 4}, each _ * 2)         // → {2, 4, 6, 8}

// Convertir textos a mayúsculas
List.Transform({"hola", "mundo"}, Text.Upper)     // → {"HOLA", "MUNDO"}

// Calcular el IVA de cada precio
List.Transform({100, 200, 50}, each _ * 1.21)    // → {121, 242, 60.5}

List.Sort

Intermedio

Sintaxis

List.Sort(lista as list, optional criterios as any) as list

Ejemplo

List.Sort({3, 1, 4, 1, 5})                        // → {1, 1, 3, 4, 5}  ascendente
List.Sort({3, 1, 4, 1, 5}, Order.Descending)      // → {5, 4, 3, 1, 1}
List.Sort({"Banana", "Manzana", "Pera"})          // → {"Banana", "Manzana", "Pera"}

List.Combine

Intermedio

Sintaxis

List.Combine(listas as list) as list

¿Qué hace?

Une múltiples listas en una sola. Recibe una lista de listas.

Ejemplo

List.Combine({{1, 2}, {3, 4}, {5, 6}})   // → {1, 2, 3, 4, 5, 6}

// Combinar dos columnas de una tabla en una sola lista
List.Combine({Tabla[Nombre], Tabla[Apellido]})

Funciones Avanzadas

List.Generate

Avanzado

Sintaxis

List.Generate(
    inicial as function,
    condicion as function,
    siguiente as function,
    optional selector as nullable function
) as list

¿Qué hace?

Genera una lista dinámicamente mediante un bucle: empieza con un valor inicial, genera el siguiente mientras se cumpla la condición. Es el equivalente a un bucle while en M. Muy potente para paginación de APIs.

Parámetros

  • inicial: función que devuelve el valor inicial (sin argumentos)
  • condicion: función que recibe el estado actual y devuelve true/false para continuar
  • siguiente: función que recibe el estado actual y devuelve el siguiente
  • selector (opcional): función que transforma cada elemento antes de añadirlo a la lista

Ejemplo 1: Generar números del 1 al 10

List.Generate(
    () => 1,              // empieza en 1
    each _ <= 10,         // mientras sea <= 10
    each _ + 1            // incrementar en 1
)
// → {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Ejemplo 2: Paginación de API REST

// Leer todas las páginas de una API hasta que devuelva vacío
let
    Paginas = List.Generate(
        () => [pagina = 1, datos = Json.Document(Web.Contents("https://api.ejemplo.com/datos?page=1"))],
        each List.Count([datos]) > 0,
        each [
            pagina = [pagina] + 1,
            datos = Json.Document(Web.Contents("https://api.ejemplo.com/datos?page=" & Text.From([pagina] + 1)))
        ],
        each [datos]
    ),
    Combinado = Table.FromRecords(List.Combine(Paginas))
in
    Combinado
💡 Tip kawaii: List.Generate es la función más poderosa para implementar lógica de bucle en M. Si necesitas repetir algo hasta que se cumpla una condición, es tu función.

List.Accumulate

Avanzado

Sintaxis

List.Accumulate(
    lista as list,
    semilla as any,
    acumulador as function
) as any

¿Qué hace?

Recorre la lista acumulando un resultado: empieza con un valor inicial (semilla) y aplica la función acumuladora a cada elemento. Es el reduce de M.

Ejemplo 1: Factorial con List.Accumulate

// 5! = 1 * 2 * 3 * 4 * 5
List.Accumulate({1..5}, 1, (acumulado, elemento) => acumulado * elemento)
// → 120

Ejemplo 2: Construir texto concatenando lista

List.Accumulate(
    {"Ana", "Luis", "María"},
    "",
    (acumulado, nombre) => if acumulado = "" then nombre else acumulado & ", " & nombre
)
// → "Ana, Luis, María"
🚀 ¡Lo estás haciendo genial! Las listas son fundamentales en M. El siguiente paso son las Funciones de Texto — las más usadas en el día a día de cualquier proyecto.