aEval
Executa codeblock para cada elemento do array. Estilo "forEach" do AdvPL. Util pra processar arrays sem montar For loop verboso.
Assinatura: aEval(aArr, bAcao, [nIni], [nQtd]) -> aArr
Retorna: Array (mesma referencia)
aEval e o "forEach" do AdvPL. Recebe array + codeblock, executa o bloco passando cada elemento como argumento. Mais conciso que For i := 1 To Len().
Sintaxe
aEval(aArr, bAcao, nIni, nQtd) --> aArr
// bAcao = codeblock {|elem, idx| ...}
// nIni = posicao inicial (default 1)
// nQtd = quantos elementos (default todos)
Exemplos
aNomes := {"Ana", "Bruno", "Carlos"}
// Imprime cada
aEval(aNomes, {|x| ConOut(x)})
// Ana
// Bruno
// Carlos
// Com indice
aEval(aNomes, {|x, i| ConOut(cValToChar(i) + ": " + x)})
// 1: Ana
// 2: Bruno
// 3: Carlos
Casos praticos
1. Aplicar transformacao em todos elementos
aValores := {10.5, 20.75, 30.99}
nTotal := 0
aEval(aValores, {|n| nTotal += n})
ConOut("Total: " + cValToChar(nTotal)) // 62.24
2. Coletar atributo
// aClientes = { {cod, nome}, {cod, nome}, ... }
Local aCodigos := {}
aEval(aClientes, {|cli| aAdd(aCodigos, cli[1])})
// aCodigos agora so com os codigos
3. Validar todos
Local lTodosOk := .T.
aEval(aRegistros, {|r| ;
If !ValidaReg(r) ; lTodosOk := .F. ; EndIf ;
})
4. Imprimir relatorio com indice
aEval(aLinhas, {|cLinha, n| ;
oReport:Section(1):Cell("LIN"):SetBlock({|| n}) ; ;
oReport:Section(1):Cell("TXT"):SetBlock({|| cLinha}) ; ;
oReport:Section(1):PrintLine() ;
})
Comparacao com For loop
// For tradicional — verboso
For i := 1 To Len(aArr)
ConOut(cValToChar(i) + " - " + aArr[i])
Next
// aEval — conciso
aEval(aArr, {|x, i| ConOut(cValToChar(i) + " - " + x)})
Pegadinhas
- Codeblock recebe (elem, indice) — sempre nessa ordem. Idx e opcional.
- Retorno do bloco e ignorado — aEval nao acumula. Pra map, precisa atribuir em variavel externa.
- Performance vs For — em arrays grandes, For e marginalmente mais rapido. aEval otimo pra ate ~10k.
- Modificar array dentro — pode bagunca iteracao. Itere snapshot ou colete mudancas em outro array.
- Break do loop — nao tem. Pra interromper, use For tradicional com Exit.
Variantes uteis
// Map (criar novo array transformado)
aDobro := {}
aEval(aArr, {|n| aAdd(aDobro, n * 2)})
// Filter (filtrar)
aPositivos := {}
aEval(aArr, {|n| If(n > 0, aAdd(aPositivos, n), NIL)})
// Reduce
nTotal := 0
aEval(aArr, {|n| nTotal += n})
Parâmetros
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
aArr | Array | sim | Array a iterar. |
bAcao | CodeBlock | sim | Block executado em cada elemento. |