Estructuras de Control Alternativas

Tomando decisiones en tu código

Te pusiste a pensar la cantidad de veces en el día que tomás decisiones que pueden afectar a tu vida o incluso la vida de los demás? Desde las menos relevantes como " ¿Me pongo la remera azul o la verde?", hasta las más cruciales como "¿Renuncio a mi trabajo para dedicarme a ser un programador freelance, mientras viajo por el mundo?"

Pensemos que estamos programando un juego en que cada vez que un jugador pierde una vida necesitamos avisarle si puede seguir jugando o no. Es decir que mientras le queden vidas, él podría seguir jugando, pero en caso contrario, tenemos que avisarle que el juego ha terminado. Este es el momento en el que, como programadores, necesitamos empezar a tomar decisiones sobre nuestro código. Estas decisiones (también llamadas condiciones) te van a modificar el flujo del programa, ya que te permiten elegir qué acciones deberá realizar el código en cada caso.
A continuación te mostramos los diferentes tipos de estructuras condicionales que existen y cómo se pueden utilizar en Javascript.

Condicional Simple: if

Con la estructura de control if podés indicarle al programa que tome cierto camino, siempre y cuando la condición sea verdadera. Llamamos condición a cualquier expresión de tipo Boolean (que se evalúe como true o false).

bloque de código anterior
 inicio alternativa
 si (condición es verdadera) entonces
	  bloque de código
	 (se ejecuta si la condición es verdadera)
 fin alternativa
								 

Sintaxis

Una declaración if en Javascript la escribimos así:

if (condición) {
 	// código a ejecutar si la condición es verdadera
 }

Las estructuras alternativas también pueden utilizarse de forma anidadas con otras alternativas.


Tip

Recordá que cuando dentro de las llaves ({ }) sólo tenés una línea, se pueden omitir dichas llaves. Aún así, siempre es recomendable ponerlas si tenemos dudas o no estamos seguros.

Tené cuidado!!

Javascript es un lenguaje Case Sensitive, es decir, diferencia entre mayúsculas y minúsculas. Tené en cuenta que if está en minúsculas. Las letras mayúsculas (If o IF) generarán un error.


Ejemplos

  1. Condicional simple: Siguiendo con el ejemplo que propusimos inicialmente, en el que estamos programando un juego y cuando el jugador se queda sin vidas necesitamos avisarle que el juego se terminó. Es decir, si sabemos la cantidad de vidas que le quedan, cuando ese valor es menor a 1, el juego se termina (lo podemos representar con el mensaje "juego terminado");

    Volviendo en el tiempo...

    En Javascript, cuando evaluamos una expresión booleana donde su valor resultante sea:

    • NaN
    • undefined
    • null
    • 0 (cero)
    • '' o "" (string vacío)

    da como resultado false. Es decir, que si el condicional de una alternativa es alguno de los valores antes mencionados, entonces NO ejecuta el bloque de código de la estructura if, ya que su condición es false.


  2. Condicional simple anidada: Qué pasaría si necesitamos enviar un mensaje al jugador, no sólo cuando se quede sin vidas, si no que queremos enviarle otro cuando le quede la última vida?
    Para este caso vamos a necesitar enviar un mensaje para cuando la cantidad de vidas sea 1 (podría ser 'Te queda la última vida') y otro para cuando la cantidad de vidas sea menor a 0 ('Juego Terminado').



Condición con alternativa: if-else

Ahora bien, qué sucede si quisieras establecer una alternativa a la condición del if. Es decir, si quisieras tomar un camino si la condición es verdadera, pero si no lo es... seguir por otro camino?
Para eso utilizamos la expresión if seguida de otra llamada else. De esta forma vamos poder establecer que se realice:

  • una acción que llamaremos A, si se cumple la condición,
  • una acción llamada B, si no se cumple la condición.

bloque de código anterior
 inicio alternativa
 si (condición es verdadera) entonces
	 bloque de código A 
	 (se ejecuta si la condición es verdadera)
 si (condición es falsa) entonces
	 bloque de código B  
	 (se ejecuta si la condición es falsa)
 fin alternativa
									

Sintaxis

Una declaración if-else se escribe de la siguiente manera:

if (condición) {
	// A: código a ejecutar si la condición es verdadera
else {
	// B: ejecuta este otro código si la condición es falsa
} 

Ejemplos

  1. Ahora imagina que seguimos programando un juego, pero esta vez queremos avisarle al jugador si puede seguir jugando o no cada vez que pierda una de sus vidas. Es decir, cada vez que el jugador pierda una vida, si le quedan vidas recibe un mensaje para que siga jugando, pero si se queda sin vidas, el juego se termina, por lo que recibe el mensaje de 'Juego Terminado'.

    Pasemos esto un poco en limpio...

    Si la cantidad de vidas del jugador es:
    • menor a 1 => se termina el juego => Juego Terminado
    • mayor o igual a 1 => el juego no ha terminado => Sigue jugando!

    Otra sintaxis if-else

    Existe otra sintaxis definida para una estructura de control if-else llamada operador ternario que tiene una forma mucho más corta y, en algunos casos, más legible. Aunque es una opción que sólo se recomienda utilizar cuando son sentencias alternativas más simples.
    variable1 = condición ? condición es true : condición es false;

    let mensaje = vidas <=  ? "Juego Terminado!" :"Sigue jugando!";
     alert(mensaje);

    En este caso, la variable mensaje va a almacenar un string u otro dependiendo del contenido de la variable vidas.

  2. Continuando con el ejemplo anterior, ahora vamos a agregarle un poco más de complejidad.
    Supongamos que una vez que el jugador pierde una vida, si éstas son menores o iguales a 0 le informamos que perdió. Pero si al jugador le quedan pocas vidas (menos de 3), ahora queremos advertirle que juegue con cuidado. Sin embargo, si le quedan 3 o más vidas, sólo querés animarlo a que siga jugando.

    Volvamos a pasarlo en limpio...

    Si cantidad de vidas del jugador es:

    • menor o igual a 0 => "Juego Terminado"
    • es mayor a 0 => el juego no ha terminado
    • es mayor o igual a 3 =>"A no preocuparse... Sigue jugando!"
    • es menor a 3 => "Ten cuidado, te quedan pocas vidas!"

Condición con alternativa múltiple (if-else if)

Es posible que necesitemos crear una alternativa múltiple con más de 2 condiciones, es decir que necesitamos especificar una nueva condición (if) si la primera es falsa. En definitiva, luego de una sentencia else necesitamos realizar una nueva condición (if). Como vimos en el ejemplo anterior, muchas veces necesitamos tener otra condición if luego de una sentencia alternativa else. A este tipo de estructuras se la conoce como sentencia else if.

Sintaxis

Una declaración if-else if se escribe de la siguiente manera:

if (condición1) {
	// bloque de código que se ejecuta si condición1 es verdadera (condición1 === true)
} else if (condición2) {
	 // bloque de código que se ejecuta si condición1 es falsa y condición2 es verdadera 
	 // (condición1 === false && condición2 === true)
} else {
	// bloque de código que se ejecuta si condición1 y condición2 son es falsas
	// (condición1 === false && condición2 === false)
}

Ejemplo

Si retomamos el último ejemplo (número 2), en el que tenemos una sentencia alternativa else (línea 6) continuada de una condicional if (línea 7), podemos considerar volver a escribir el código de la siguiente manera:

Condición múltiple: switch

Hasta ahora hemos aprendido muchas estructuras, incluso todas las alternativas necesarias para poder empezar a tomar decisiones en el código. Pero qué pasaría si en el juego que estamos programando van a haber jugadores de distintos países, y cada vez que un jugador pierda el juego, querés avisarle que el "juego finalizó" en un idioma que pueda interpretar. Si consideramos que inicialmente hay 3 idiomas (ESP: Español, ING: Inglés y ALE: Alemán), cómo lo podemos representar?
Veamos una posible solución...

Este ejemplo ya lo deducimos rápido, incluso quizás se te ocurre otra forma de resolverlo con las estructuras que ya vimos. Pero qué pasaría si la cantidad de idiomas son más, por ejemplo unos 10 idiomas distintos... se te ocurre cuántas estructuras de control alternativas necesitaríamos?...
Y veamos... por 3 idiomas => 3 estructuras if...
Sí, si pensaste bien... vamos a necesitar al menos 10 estructuras de control condicionales!!!
¿Te animás a sumarlas en el ejemplo anterior? te damos una ayuda con las abreviaturas que podés utilizar:

  • ESP: Español
  • ING: Inglés
  • ALE: Alemán
  • POR: Portugués
  • FRA: Fancés
  • RUS: Ruso
  • CHN: Chino
  • JPN: Japonés
  • ARB: Árabe
  • TUR: Turco

Bien, ahora que ya lo resolviste y podes ver "claramente" el código... no te parece que esto resulta muy difícil de leer? el código se torna bastante extenso y, dependiendo de cómo lo hayas resuelto, posiblemente tengas estructuras cada vez más anidadas entre si, lo que lo hace muy difícil de seguir. Ufff... ni pensar si nos piden que agreguemos más idiomas!
Pero tenemos una solución para esto! Con la idea de reducir la sintaxis de este tipo de problemas, es que existen las estructuras con condicionales múltiples, en Javascript es llamada sentencia switch.
La sentencia switch es utilizada cuando se desea realizar múltiples condiciones sobre una misma expresión.

bloque de código anterior
 inicio switch
  si (Espresión === X1) entonces
	  bloque de código X1
  si (Espresión === x2) entonces
	 bloque de código x2
	 . 
	 . 
	 . 
  si (Espresión === Xn) entonces
	 bloque de código Xn
  si (Espresión no es igual a 
     X1, X2,... o Xn) entonces
	 bloque de código default optativo (n+1) 	
 fin alternativa 

Sintaxis

Una declaración switch en Javascript se escribe de la siguiente manera:

switch(expression) {
	case x1:
		// bloque de código 1
		break;
	case x2:
		// bloque de código 2
		break;
		.
		.
		.
	case xn:
		// bloque de código n
		break;
	default:
	// bloque de código n+1
}

Ahora veamos una descripción de las características de este tipo de estructuras:

  • Cuando se lee la sentencia switch se verifica la igualdad estricta (===) entre el caso case
    (x1, x2, ..., xn) y la expresión expression. Si uno de los casos coincide con la expresión expression, se ejecutará el bloque de código dentro de la cláusula del caso case, hasta que encuentre el final de la declaración switch o hasta encontrar una interrupción break. Es decir, que si expression === x1 es verdadero, entonces se ejecutará el bloque de código 1, pero si expression === x1 es falso, se seguirá con la misma comparación para los demás casos case (x2, ..., xn), hasta dar con alguno que sea verdadero.
  • Si más de un caso coincide con la instrucción switch, se ejecutará el primer caso case que coincida con la expresión expression. Si ninguno de los casos coincide con la expresión, se ejecutará la cláusula predeterminada default.
  • La instrucción break está asociada con cada etiqueta case y permite salir de la estructura de código case que estemos ejecutando, por lo que una vez que ejecutemos la instrucción break se finaliza la ejecución de la estructura switch.

Ejemplo

Bien, ahora veamos cómo podemos resolver el ejemplo anterior, con esta nueva estructura.
Repasemos un poco el problema...
Seguimos programando un juego en el que cada vez que un jugador se quede sin vidas necesitamos avisarle que el juego se ha terminado. Pero este mensaje debe ser en un idioma que el jugador entienda. Ya vimos cómo podemos implementarlo para 3 idiomas distintos, vos lo probaste con 10, pero ahora queremos que estos 10 idiomas sean comparados con estructuras condicionales múltiples.

Consideremos los siguientes idiomas (con sus abreviaturas como identificadores):

  • ESP: Español
  • ING: Inglés
  • ALE: Alemán
  • POR: Portugués
  • FRA: Fancés
  • RUS: Ruso
  • CHN: Chino
  • JPN: Japonés
  • ARB: Árabe
  • TUR: Turco

Como podemos observar ahora la sintaxis del código es mucho más simple, incluso si necesitaramos agregar nuevos idiomas ya no resultaría tan difícil de seguir. ¿Te animás a agregarle dos idiomas más al ejemplo anterior? te dejo dos orientativos por si querés usarlos:
CAT: Catalán. Traducción de 'Juego terminado' => 'joc acabat'.
POL: Polaco. Traducción de 'Juego terminado' => 'koniec gry'.

También se aplica

La instrucción break es opcional, pero si no está presente la ejecución continuará a través de las sentencias case, aunque no se encuentre coincidencia. Es decir, ejecutará todas las sentencias siguientes hasta encontrar una instrucción break o hasta que finalice la estructura switch.
Podemos omitir el uso de break para "agrupar" casos case, es decir podemos decidir ejecutar cierto bloque de código para un conjunto de casos case y otro/s bloque/s de código distinto para otros casos case.

A trabajar!

Ahora que ya vimos el concepto de estructuras alternativas y cómo utilizarlas dentro de JavaScript, vamos a emplear estos conocimientos, en conjunto con todo lo que hemos aprendido en los recorridos anteriores, para resolver distintos desafíos de programación.
En la carpeta R3, vamos a crear un archivo para cada ejercicio en el que podés nombrarlo de la siguiente forma "alternativas_nivelx.js", donde x es el número del nivel que tiene el ejercicio.

Nivel 1: Refactorizando nuestro código

Ejercicio propuesto:

Nivel 2: Programando el tiempo

Ejercicio propuesto:

Nivel 3: Notificando Salidas

Ejercicio propuesto:

Nivel 4: A rendir Examen! :o

Parte 1:
Parte 2:

Nivel 5: Analizando condicionales con alternativas

Nivel 6: Categorizando usuarios

Ejercicio propuesto:

Nivel 7: Menú de atención al usuario

Ejercicio propuesto:

Nivel 8: Calculadora

Ejercicio propuesto:

Nivel 9: Alarma

Ejercicio propuesto:

Nivel 10: Cambiando colores

Ejercicio propuesto:

Adicionales

Ahora que ya estás a full con los ejercicios de alternativas, te proponemos una serie de desafíos para poner aún más a prueba tus conocimientos y profundizar lo aprendido. Suerte!

Adicional 1: IMC

Ejercicio propuesto:

Adicional 2: Tipo de sustancia

Ejercicio propuesto:

Adicional 3: Más refactor

Ejercicio propuesto:
Separador Visual

Desafío Dipli! - ¿Cuál es el Número?

Considerando todo lo que hemos aprendido durante este recorrido, te proponemos que pienses en el desafío Dipli del recorrido de funciones y trates de incorporar las nuevas estructuras aprendidas: Alternativas.
Además de respetar las reglas ya planteadas en desafíos anteriores, también vamos aconsiderar que el desadío Dipli responda a las siguientes reglas:

  • El jugador debería poder jugar al menos 3 veces (tener al menos 3 intentos), pero los siguientes intentos sólo deberán ser posible si en el primero no ganó.
  • Antes de cada nuevo intento el jugador deberá saber que no acertó el anterior.
  • Al comienzo del juego se le debe informar al jugador el rango de valores que puede ingresar. Si el jugador ingresa valores fuera del rango pierde ese turno, y se le debe avisar que perdió esa oportunidad por estar fuera del rango de valores que puede elegir Dipli.

TIPS!

Ahora que ya incorporamos nuevas herramientas podemos cambiar algunos mensajes, como por ejemplo:
"Ganó Dipli: true", "Ganó Contrincante: false",
puede ser modificado por: "El ganador es Dipli", o el que mejor te parezca ;)

Suerte y a disfrutar programando!

info

Repaso!

    Veamos que recordamos de lo que transitamos en este recorrido:

  • En una estructura alternativa, la condición es una expresión de qué tipo?

    Boolean
  • En una estructura alternativa cuándo se ejecuta la sentencia else?

    Cuando la condición es falsa (false).
  • Qué alert se va a observar:
    let variable = 0;
    if (variable) { alert("Ingresa if"); }
    else { alert("Ingresa else"); }

    El alert que contiene el string: "Ingresa else"
  • Qué alert se va a observar:
    let variable = 2;
    if (variable) { alert("Ingresa if"); }
    else { alert("Ingresa else"); }

    El alert que contiene el string: "Ingresa if"
  • Con qué tipo de Estructura se pueden realizar múltiples condiciones sobre una misma expresión?

    Estructura condicional múltiple (switch)
  • Una instrucción switch(dato){...} qué operador utiliza para comparar el contenido de "dato" con el valor de cada caso (case)?

    Operador de comparación igual valor y tipo (===).
Separador Visual