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.
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.
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.
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.
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.