Saltar al contenido principal

Clase 03 — Arrays en JSON

Un array es una lista ordenada de valores, encerrada entre [ ].

Reglas de los arrays

  1. Los valores se separan con comas
  2. Pueden contener cualquier tipo de dato JSON
  3. Pueden mezclar tipos (aunque no es recomendable)
  4. No puede haber coma después del último elemento
  5. Los elementos se acceden por índice (empezando en 0)

Arrays simples

{
"numeros": [1, 2, 3, 4, 5],
"nombres": ["Ana", "Carlos", "María"],
"booleanos": [true, false, true],
"vacio": []
}

Arrays de objetos

La forma más común en APIs y configuraciones:

{
"usuarios": [
{ "id": 1, "nombre": "Ana García", "rol": "backend", "activo": true },
{ "id": 2, "nombre": "Carlos López", "rol": "devops", "activo": true },
{ "id": 3, "nombre": "María Ruiz", "rol": "frontend", "activo": false }
]
}

Arrays anidados

{
"matriz": [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
"equipos": [
{ "nombre": "Backend", "miembros": ["Ana", "Pedro"], "tecnologias": ["Python", "FastAPI"] },
{ "nombre": "Frontend", "miembros": ["María", "Jorge"], "tecnologias": ["React", "TypeScript"] }
]
}

Acceder a arrays con jq

# Primer elemento (índice 0)
jq '.usuarios[0]' usuarios.json

# Último elemento
jq '.usuarios[-1]' usuarios.json

# Todos los nombres
jq '.usuarios[].nombre' usuarios.json

# Como array
jq '[.usuarios[].nombre]' usuarios.json
# ["Ana", "Carlos", "María"]

# Rango (primeros 2)
jq '.usuarios[0:2]' usuarios.json

# Longitud del array
jq '.usuarios | length' usuarios.json

Filtrar arrays con jq

# Usuarios activos
jq '[.usuarios[] | select(.activo == true) | .nombre]' usuarios.json
# ["Ana", "Carlos"]

# Usuarios con rol "devops"
jq '.usuarios[] | select(.rol == "devops")' usuarios.json

# Usuarios con id mayor a 1
jq '[.usuarios[] | select(.id > 1)]' usuarios.json

Transformar arrays con jq

# Map — transformar cada elemento
jq '[.usuarios[] | {name: .nombre, role: .rol}]' usuarios.json

# Ordenar
jq '.usuarios | sort_by(.nombre)' usuarios.json

# Ordenar descendente
jq '.usuarios | sort_by(.id) | reverse' usuarios.json

# Group by
jq '.usuarios | group_by(.activo)' usuarios.json

# Unique
echo '[1,2,2,3,3,3]' | jq 'unique'
# [1, 2, 3]

# Flatten (aplanar arrays anidados)
echo '[[1,2],[3,4],[5]]' | jq 'flatten'
# [1, 2, 3, 4, 5]

Ejemplo: Respuesta de API paginada

{
"page": 1,
"per_page": 3,
"total": 12,
"data": [
{ "id": 1, "name": "pikachu", "type": ["electric"], "hp": 35, "speed": 90 },
{ "id": 4, "name": "charmander", "type": ["fire"], "hp": 39, "speed": 65 },
{ "id": 7, "name": "squirtle", "type": ["water"], "hp": 44, "speed": 43 }
]
}
# Nombres de los pokémon
jq '[.data[].name]' pokemon.json

# Pokémon con speed > 50
jq '[.data[] | select(.speed > 50) | .name]' pokemon.json

# Pokémon más rápido
jq '.data | max_by(.speed) | {name, speed}' pokemon.json

# Promedio de HP
jq '.data | map(.hp) | add / length' pokemon.json

# Tabla formateada
jq -r '.data[] | "\(.id)\t\(.name)\t\(.hp)\t\(.speed)"' pokemon.json

Ejemplo: AWS CLI — Instancias EC2

# Todas las instancias con su nombre y estado
jq '.Reservations[].Instances[] | {
id: .InstanceId,
tipo: .InstanceType,
estado: .State.Name,
nombre: (.Tags[] | select(.Key == "Name") | .Value),
ip: .PublicIpAddress
}' ec2.json

# Solo instancias running
jq '[.Reservations[].Instances[] | select(.State.Name == "running")]' ec2.json

# IPs públicas de instancias activas
jq '[.Reservations[].Instances[] | select(.State.Name == "running") | .PublicIpAddress // "N/A"]' ec2.json