Apex Academy
Módulo 2·05·24 min

For Loop y sus variantes

Recorrer una lista registro a registro: el elemento Loop de Flow, en una línea. Y el for clásico, para cuando cuentas vueltas.

En Admin esEl elemento Loop de Flow sobre una variable de colección

✓ En esta sub-lección

  1. 01Recorrer una List, un Set o los valores de un Map con un for-each.
  2. 02Escribir un for clásico con sus tres partes cuando lo que cuentas son vueltas.
  3. 03Aplicar los dos patrones más útiles dentro de un bucle: acumular y filtrar.

La nutria: ¿Te acuerdas? · Repaso de la lección 4

En un while, ¿qué pasa si nada dentro del cuerpo cambia la condición?

Casi todo el Apex real hace lo mismo: recibe una lista de registros y hace algo con cada uno. Un trigger recibe hasta un ; una consulta devuelve una lista. El bucle for es la herramienta para eso, y es el que más vas a escribir.

La nutria: El paralelo de Admin

En Flow, el elemento Loop me pedía dos cosas: la variable de colección que quería recorrer y una variable para el «elemento actual». Dentro del bucle trabajaba con ese elemento actual, y al terminar la colección salía por «After Last Item». El for-each de Apex pide exactamente lo mismo, en el mismo orden.

For-each: un registro cada vez

Apex
List<Opportunity> opps = new List<Opportunity>{
    new Opportunity(Name = 'Acme', Amount = 12000),
    new Opportunity(Name = 'Globex', Amount = 45000)
};

for (Opportunity opp : opps) {
    System.debug(opp.Name + ': ' + opp.Amount);
}
Léelo como «para cada Opportunity opp de opps». opp es el elemento actual; en cada vuelta apunta al siguiente registro.
for (Opportunity opp : opps) { total += opp.Amount; if (opp.StageName == 'Negotiation') inNegotiation++; }
  1. opp →Northwind · RenovaciónNegotiation24.500
  2. Acme · LicenciasProspecting40.000
  3. Initech · PlantaNegotiation120.000
  4. Globex · PilotoQualification15.000

total

0

inNegotiation

0

Paso 1 de 5

Vuelta 1 de 4: opp es «Northwind · Renovación». Se suma su importe y, como está en Negotiation, cuenta también.

Las mismas piezas que el elemento Loop de Flow: la colección, el elemento actual y lo que se hace con él.

Tú no llevas la cuenta de nada: el bucle hace tantas como elementos haya, en orden, y si la lista está vacía no entra ni una vez. El tipo del elemento actual tiene que coincidir con el de la colección: para una List<Contact>, el elemento es un Contact. Y en la mayoría de org, esa lista vendrá de una consulta ; aquí la construimos a mano porque eso llega en el Módulo 3.

Recorrer un Set o un Map

Un Set se recorre igual que una List, aunque sin orden garantizado. Un Map no se recorre directamente: le pides una de sus dos caras. keySet() devuelve el Set de claves y values() la List de valores.

Apex
Map<String, Decimal> quotaByRegion = new Map<String, Decimal>{
    'EMEA' => 500000,
    'APAC' => 300000
};

for (String region : quotaByRegion.keySet()) {
    System.debug(region + ' → ' + quotaByRegion.get(region));
}

Decimal totalQuota = 0;
for (Decimal quota : quotaByRegion.values()) {
    totalQuota += quota;
}
totalQuota += quota es el atajo de totalQuota = totalQuota + quota.

Los dos patrones que más vas a usar

Acumular: declaras un total antes del bucle y le sumas algo en cada vuelta. Filtrar: declaras una lista vacía antes del bucle y le añades solo los elementos que cumplen una condición. En los dos casos la variable se declara fuera: si la declarases dentro, se reiniciaría en cada vuelta y moriría al terminar, como viste en ámbito.

Apex
Decimal openPipeline = 0;                        // acumular
List<Opportunity> bigDeals = new List<Opportunity>(); // filtrar

for (Opportunity opp : opps) {
    Decimal amount = opp.Amount ?? 0;
    openPipeline += amount;
    if (amount >= 40000) {
        bigDeals.add(opp);
    }
}
amount sí se declara dentro: solo hace falta durante una vuelta.

El for clásico: contar vueltas

Cuando lo que necesitas es un número que va avanzando (generar 12 cuotas mensuales, o saber en qué posición de la lista estás), el for clásico tiene tres partes separadas por punto y coma: dónde empieza el contador, mientras qué condición sigue, y cuánto avanza tras cada vuelta.

Apex
for (Integer month = 1; month <= 12; month++) {
    System.debug('Cuota del mes ' + month);
}

for (Integer i = 0; i < opps.size(); i++) {
    System.debug((i + 1) + '. ' + opps[i].Name);
}
Es un while con el contador, la condición y el avance escritos en una sola línea. Los índices de una List empiezan en 0, así que la condición es i < size(), no i <= size().
Necesitas…Usa
Hacer algo con cada registro de una listafor (Tipo x : lista)
Un número que avanza, o la posiciónfor (Integer i = 0; …; i++)
Repetir hasta que un valor cambiewhile