Descargar

6. Colecciones

Listas

Una lista guarda valores en orden. Los índices empiezan en 0 y los negativos cuentan desde el final.

var numeros = [5, 3, 8, 1]
numeros.add(10)
print(numeros[0], numeros[-1], numeros.length)
print(numeros[1..3])                 // trozo: índices 1 y 2
numeros[0] = 50
print(numeros.contains(8), numeros.indexOf(8))
print(numeros.copy().sort(), numeros.sum(), numeros.min(), numeros.max())
▶ Probar en el editor

Métodos más usados (la lista completa está en la API):

MétodoQué hace
add(x) insert(i, x)añadir al final / en una posición
pop() shift() removeAt(i) remove(x)quitar el último / el primero / por posición / por valor
map(f) filter(f) reduce(f, inicial)transformar, filtrar y acumular
find(f) findIndex(f) any(f) all(f) count(f)buscar
sort() sortBy(f) reverse() reversed() shuffle()ordenar (en el sitio o una copia)
join(sep) unique() take(n) skip(n) chunk(n) zip(otra) flat()otras
groupBy(f) minBy(f) maxBy(f) average() partition(f)agrupar y resumir
var jugadores = [{ nombre: "Ana", puntos: 120 }, { nombre: "Luis", puntos: 95 }, { nombre: "Eva", puntos: 130 }]
var ranking = jugadores.sortBy(j => -j.puntos).map(j => j.nombre)
print(ranking, jugadores.maxBy(j => j.puntos).nombre, jugadores.map(j => j.puntos).average())
▶ Probar en el editor

Mapas

Un mapa asocia claves (normalmente textos) con valores. Las claves que son nombres válidos se pueden usar con punto.

var jugador = { nombre: "Ana", vida: 3 }
jugador.oro = 10
jugador["nivel"] = 2
print(jugador.nombre, jugador["vida"], jugador.keys(), jugador.values())
print(jugador.has("oro"), jugador.get("mana", 0))
jugador.remove("oro")
foreach clave, valor in jugador { print(clave, "=", valor) }
▶ Probar en el editor

Conjuntos

Un conjunto guarda valores sin repetir:

var vistos = set(1, 2, 2, 3)
vistos.add(4)
print(vistos.length, 2 in vistos, vistos)
▶ Probar en el editor

Rangos

var r = 1..=5
print(r.toList(), 3 in r, len(r))
foreach i in 0..10 step 4 { print(i) }
▶ Probar en el editor

Desestructuración

Saca varios valores de una lista o de un mapa (u objeto) a la vez:

var [primero, segundo, ...resto] = [10, 20, 30, 40]
print(primero, segundo, resto)          // 10 20 [30, 40]

var {nombre, vida} = { nombre: "Ana", vida: 3 }
print(nombre, vida)

var {x, y: alto} = Vec2(3, 4)           // {campo: otroNombre} cambia el nombre
print(x, alto)

function extremos(l: list): list { return [l.min(), l.max()] }
const [minimo, maximo] = extremos([4, 9, 1])
print(minimo, maximo)
▶ Probar en el editor

Si a la lista le faltan elementos, es un error en ejecución (índice fuera de rango).

Repetir una lista

print([0] * 5)                 // [0, 0, 0, 0, 0]
print([1, 2] * 3)              // [1, 2, 1, 2, 1, 2]
var tablero = range(3).toList().map(i => ["."] * 3)   // cada fila es una lista distinta
tablero[0][0] = "X"
print(tablero)
▶ Probar en el editor

Como "ab" * 3 con los textos. Ojo: [[0] * 3] * 3 repetiría la misma fila tres veces; para una cuadrícula crea cada fila por separado, como arriba.

Comprensiones

Una lista (o un mapa) a partir de otra colección, en una sola línea: [expresión for x in colección if condición].

print([x * x for x in 1..=5])                  // [1, 4, 9, 16, 25]
print([x for x in [5, 1, 8, 3] if x > 2])      // [5, 8, 3]
print([i * 10 + x for i, x in [1, 2, 3]])      // con la posición: [1, 12, 23]
print([x for x in 0..10 step 4])               // [0, 4, 8]
print([[y * x for y in 1..=3] for x in 1..=2]) // anidadas: [[1, 2, 3], [2, 4, 6]]

print({n: n * n for n in 1..=3})               // mapa: {1: 1, 2: 4, 3: 9}
print({k: v * 10 for k, v in {a: 1, b: 2}})    // {a: 10, b: 20}
▶ Probar en el editor

Es lo mismo que un bucle que va añadiendo a una lista, pero más corto. En una comprensión de mapa la clave es una expresión (como si llevara corchetes). Dentro no se puede usar await.

Propagación en mapas

...otro copia las entradas de otro mapa dentro de uno nuevo; las claves que van después ganan:

var base = {color: "azul", tamano: 2}
print({...base, tamano: 5})        // {color: azul, tamano: 5}
print({id: 1, ...base})            // {id: 1, color: azul, tamano: 2}
var copia = {...base}              // copia independiente
copia.color = "rojo"
print(base.color)                  // azul
▶ Probar en el editor

Trozos con rangos

Un rango dentro de los corchetes devuelve un trozo (de una lista o de un texto). Los extremos se pueden omitir y los negativos cuentan desde el final:

var l = [1, 2, 3, 4, 5, 6]
print(l[1..3], l[2..], l[..2], l[..=2], l[-2..])   // [2, 3] [3, 4, 5, 6] [1, 2] [1, 2, 3] [5, 6]
print("Programar"[3..], "Programar"[..3])          // gramar Pro
print(l[..])                                         // copia de toda la lista
▶ Probar en el editor