4D v18

For each...End for each

Inicio

 
4D v18
For each...End for each

For each...End for each  


 

 

La sintaxis formal de la estructura repetitiva o bucle For each...End for each es la siguiente:

 For each(Current_Item;Expression{;begin{;end}}){Until|While}(Boolean_Expression)}
    statement(s)
 End for each

La estructura For each...End for each ejecuta el ciclo de instrucciones definidas para cada Elemento_actual de Expresion.  El tipo Elemento_actual depende del tipo de Expresion. El bucle For each...End for each puede iterar a través de tres tipos de Expresion:

  • colecciones: bucle en cada elemento de la colección,
  • entity selections: bucle a través de cada entidad,
  • objetos: bucle en cada propiedad del objeto.

La siguiente tabla compara los tres tipos de For each...End for each:

Bucle en coleccionesBucle en entity selectionsBucle en objetos
Tipo Current_ItemVariable del mismo tipo que los elementos de la colecciónEntityVariable texto
Tipo ExpressionColección (con elementos del mismo tipo) Selección de entidadObjeto
Número de bucles (por defecto)Número de elementos de la colecciónNúmero de entidades en la selecciónNúmero de propiedades de objetos
Soporte de Parámetros inicio/finNo
  • El número de bucles se evalúa al inicio y no cambiará durante el procesamiento. Por lo general, no se recomienda agregar o eliminar elementos durante el ciclo, ya que puede dar como resultado iteraciones faltantes o redundantes.
  • Por defecto, las instrucciones adjuntas se ejecutan para cada valor en Expresion. Sin embargo, es posible salir del bucle probando una condición ya sea al comienzo del bucle (While) o al final del bucle (Until).
  • Los parámetros opcionales inicio y fin se pueden usar con colecciones y selecciones de entidades para definir los límites del bucle.

Cuando For each...End for each se usa con una Expresion de tipo Collection, el parámetro Elemento_actual es una variable del mismo tipo que los elementos de la colección. Por defecto, el número de bucles se basa en la cantidad de elementos de la colección.

La colección debe contener solo elementos del mismo tipo; de lo contrario, se devolverá un error tan pronto como a la variable Elemento_actual se le asigne el primer valor de tipo diferente.

En cada iteración de bucle, la variable Elemento_actual se llena automáticamente con el elemento coincidente de la colección. Los siguientes puntos deben tenerse en cuenta:

  • Si la variable Elemento_actual es de tipo objeto o colección (es decir, si Expresion es una colección de objetos o de colecciones), modificar esta variable modificará automáticamente el elemento correspondiente de la colección (porque los objetos y las colecciones comparten las mismas referencias). Si la variable es de tipo escalar, solo se modificará la variable.
  • La variable Elemento_actual debe ser del mismo tipo que los elementos de la colección. Si algún elemento de la colección no es del mismo tipo que la variable, se genera un error y el ciclo se detiene.
  • Si la colección contiene elementos con un valor Null, se generará un error si el tipo de variable Elemento_actual no admite valores Null (como las variables entero largo).
Ejemplo  

Usted desea calcular algunas estadísticas para una colección de números:

 C_COLLECTION($nums)
 $nums:=New collection(10;5001;6665;33;1;42;7850)
 C_LONGINT($item;$vEven;$vOdd;$vUnder;$vOver)
 For each($item;$nums)
    If($item%2=0)
       $vEven:=$vEven+1
    Else
       $vOdd:=$vOdd+1
    End if
    Case of
       :($item<5000)
          $vUnder:=$vUnder+1
       :($item>6000)
          $vOver:=$vOver+1
    End case
 End for each
  //$vEven=3, $vOdd=4
  //$vUnder=4,$vOver=2

Cuando For each...End for each se utiliza con una Expresion de tipo Entity selection, el parámetro Elemento_actual contiene la entidad que se procesa actualmente.

El número de bucles se basa en el número de entidades en la entity selection. En cada iteración del bucle, el parámetro Elemento_actual recibe automáticamente la entidad que está siendo procesada.

Nota: si la entity selection contiene una entidad que fue eliminada mientras tanto por otro proceso, se omite automáticamente durante el ciclo.

Tenga en cuenta que cualquier modificación que se aplique a la entidad actual se debe guardar explícitamente utilizando entity.save( ).

Ejemplo  

Desea elevar el salario de todos los empleados británicos en una entity selection:

 C_OBJECT(emp)
 For each(emp;ds.Employees.query("country='UK'"))
    emp.salary:=emp.salary*1,03
    emp.save()
 End for each

Cuando For each...End for each se usa con una Expresion del tipo Objeto, el parámetro Elemento_actual es una variable texto que se completa automáticamente con el nombre de la propiedad actualmente procesada.

Las propiedades del objeto se procesan según su orden de creación. Durante el ciclo, las propiedades pueden agregarse o eliminarse del objeto, sin modificar el número de bucles que permanecerán basados en el número original de propiedades del objeto.
Ejemplo  

Desea cambiar los nombres a mayúsculas en el siguiente objeto:

{
    "firstname": "gregory",
    "lastname": "badikora",
    "age": 20
}

Puedo escribir:

 For each(property;vObject)
    If(Value type(vObject[property])=Is text)
       vObject[property]:=Uppercase(vObject[property])
    End if
 End for each

{
    "firstname": "GREGORY",
    "lastname": "BADIKORA",
    "age": 20
}

Puede definir límites para la iteración utilizando los parámetros opcionales inicio y fin.

Nota: los parámetros inicio y fin solo se pueden usar en iteraciones a través de colecciones y de las entity selections (se ignoran en las propiedades de objetos).

  • En el parámetro inicio, pase la posición del elemento en Expresion en donde comenzar la iteración (se incluye inicio).
  • En el parámetro fin, también puede pasar la posición del elemento en Expresion en donde detener la iteración (se incluye fin).  

Si fin se omite o si fin es mayor que el número de elementos en Expresion, los elementos se iteran desde inicio hasta el último (incluido).

Si los parámetros inicio y fin son valores positivos, representan las posiciones reales de los elementos en Expresion.

Si inicio es un valor negativo, se vuelve a calcular como inicio:=inicio+Tamaño expresion (se considera como el desplazamiento desde el final de Expresion). Si el valor calculado es negativo, inicio toma el valor 0.
Nota: incluso si inicio es negativo, la iteración se sigue realizando en el orden estándar.
Si fin es un valor negativo, se vuelve a calcular como fin:=fin +Tamaño expresion

Por ejemplo:

  • una colección contiene 10 elementos (numerados de 0 a 9)
  • inicio=-4 -> inicio=-4+10=6 -> la iteración comienza en el 6to elemento (#5)
  • fin=-2 -> fin=-2+10=8 -> la iteración se detiene antes del 8° elemento (#7), es decir, en el 7mo elemento.
Ejemplo  

 C_COLLECTION($col;$col2)
 $col:=New collection("a";"b";"c";"d";"e")
 $col2:=New collection(1;2;3)
 C_TEXT($item)
 For each($item;$col;0;3)
    $col2.push($item)
 End for each
  //$col2=[1,2,3,"a","b","c"]
 For each($item;$col;-2;-1)
    $col2.push($item)
 End for each
  //$col2=[1,2,3,"a","b","c","d"]

Puede controlar la ejecución de For each...End for each agregando una condición Until o While al bucle. Cuando una instrucción Until (condición) o While (condicion) está asociada al bucle, la iteración se detendrá tan pronto como la condicion se evalúe como true.

Puede pasar cualquiera de las palabras claves según sus necesidades:

  • La condición Until se prueba al final de cada iteración, por lo que si Expresion no está vacía o null, el bucle se ejecutará al menos una vez.
  • La condición While se prueba al comienzo de cada iteración, por lo que de acuerdo con el resultado de la condición, es posible que el bucle no se ejecute en absoluto.
Ejemplo  

 $colNum:=New collection(1;2;3;4;5;6;7;8;9;10)
 
 $total:=0
 For each($num;$colNum)While($total<30) //probado al inicio
    $total:=$total+$num
 End for each
 ALERT(String($total)) //$total = 36 (1+2+3+4+5+6+7+8)
 
 $total:=1000
 For each($num;$colNum)Until($total>30) //probado al final
    $total:=$total+$num
 End for each
 ALERT(String($total)) //$total = 1001 (1000+1)

El bucle For each...End for each se puede usar en una colección compartida o en un objeto compartido.

Si su código necesita modificar uno o más elementos de la colección o de las propiedades del objeto, debe usar las palabras claves Use...End use. Dependiendo de sus necesidades, puede llamar a las palabras claves Use...End use:

  • antes de ingresar al bucle, si los elementos se deben modificar juntos por razones de integridad, o 
  • dentro del ciclo cuando solo se necesitan modificar algunos elementos/propiedades y no se requiere gestión de integridad.

 
PROPIEDADES 

Producto: 4D
Tema: Presentación del lenguaje

 
CONTENIDO DE LA PÁGINA 
 
HISTORIA 

Creado por: 4D v17

 
ARTICLE USAGE

Manual de lenguaje 4D ( 4D v18)