Operador ternario

(Redirigido desde «?:»)

En informática un operador ternario (a veces incorrectamente llamado operador terciario) es un operador que toma tres argumentos. Este operador ternario puede pasar varias líneas de código a una sola línea en lenguajes que puedan usarlo tales como JavaScript, C, C# o Java. Los argumentos y el resultado puede ser de diferentes tipos. Originalmente proviene de BCPL, cuyo sintaxis equivalente para e1 ? e2: e3 era e1 -> e2, e3.[1]​ Lenguajes derivados del BCPL tienden a aparecer con este operador.

Muchos lenguajes de programación que utilizan la sintaxis del lenguaje C utilizan un operador ternario,?:, que define una sentencia condicional. Dado que este operador es a menudo el único operador ternario existente en el lenguaje de programación, a veces es referido simplemente como "el operador ternario".

La mayoría de los lenguajes de programación que se enfatizan en la programación funcional no necesitan dicho operador como su expresión regular condicional (s) es una expresión en primer lugar, por ejemplo, la expresión sistema (si (a>b) x y) es equivalente en la semántica de la expresión C (a> b)? x : y.

Este es también el caso en muchos lenguajes imperativos, empezando con ALGOL en el que sería posible escribir resultado := if a > b then x else y, también Smalltalk (resultado := (a > b) ifTrue: [ x ] ifFalse: [ y ]) o Ruby (resultado = if a > b: x else y end).

Asignación condicional

editar

La sintaxis del operador ternario (?:) se utiliza como sigue:[2]

expresión boleana ? valor si cierto : valor si falso

La condición es evaluada verdadera o falsa como una expresión booleana. Sobre la base de la evaluación de la condición de Booleana, la expresión entera devuelve valor si cierto si la condición es verdadera, pero valor si falso en caso contrario. Por lo general, las dos sub-expresiones valor si cierto y valor si falso deben tener el mismo tipo, lo cual determina el tipo de toda la expresión. La importancia de este tipo de control se encuentra en el uso más común del operador --en declaraciones de asignación condicional. En este uso aparece como una expresión en el lado derecho de una sentencia de asignación, de la siguiente manera:

variable = condición ? valor si cierto : valor si falso

El operador ?: es similar a la manera como funcionan las expresiones condicionales (if-then-else) en lenguajes de programación funcional, como Scheme, ML y Haskell, puesto que if-then-else forma una expresión en lugar de una declaración en esos idiomas.

El uso más común de este operador ternario es hacer una breve sentencia condicional. Por ejemplo, si queremos desarrollar código en C para cambiar las horas de apertura de una tienda a 12:00 del mediodía los fines de semana y 9 en punto entre semana, podemos usar:

int tiempo_de_apertura = (día == FIN_DE_SEMANA) ? 12 : 9;

en lugar del código más detallado

int tiempo_de_apertura;

if (día == FIN_DE_SEMANA)
    tiempo_de_apertura = 12;
else
    tiempo_de_apertura = 9;

Las dos formas son casi equivalentes. Tenga en cuenta que el ?: es una expresión y if-then-else una declaración. También hay que tomar en cuenta que ni el valor si es verdadero ni valor si falso pueden ser omitidos en el operador ternario, lo cual resultaría en un error por el compilador. Esto contrasta con sentencias de if..else, donde se puede omitir la cláusula else.

En C++, hay situaciones donde el uso de asignación condicional de if-else no es posible, ya que esta lengua distingue explícitamente entre inicialización y asignación. En tal caso, siempre es posible utilizar una llamada a la función, pero esto puede ser incómodo y poco elegante. Por ejemplo, si desea pasar valores con condiciones diferentes como un argumento para un constructor de un campo o una clase base, no es posible utilizar un simple if-else, en este caso podemos usar una expresión de asignación condicional, o una llamada a la función. Hay que tomar en cuenta también que algunos tipos permiten la inicialización, pero no permiten la asignación, o incluso el operador de asignación hace cosas totalmente diferente a la del constructor. Esto último es válido para los tipos de referencia, por ejemplo:

#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
int main(int argc, char *argv[])
{
    string name;
    ofstream fout;
    if (argc > 1 && argv[1])
    {
        name = argv[1];
        fout.open(name.c_str(), ios::out | ios::app);
    }
 
    ostream &sout = name.empty() ? cout : fout;
}

En este caso no hay posibilidad de sustituir el uso del operador ?: con un if-else. (Aunque se puede sustituir el uso de ?: con una llamada a la función, dentro del cual puede ser un if-else.) Además, el operador ternario puede dar un Ivalue, es decir, un valor al cual otro valor se le puede asignar. Consideremos el siguiente ejemplo:

  #include <iostream>
  int main () 
  {
     int a=0, b=0;
 
     const bool cond = ...;
     (cond ? a : b) = 1;
     std::cout << "a=" << a << ','
               << "b=" << b << '\n';
  }

Ejemplo

editar
class Ejemplo
{
   static void Main()
   {
            var a = 0;
            var b = 1;
            var r = a == b ? "Es igual" : "No es igual";
            Console.WriteLine(r);

   }
}
/*
Resultado:
No es igual
*/

CFML (Railo)

editar

Ejemplo 1

editar
<cfscript>
arg = "T";
vehicle = ( ( arg == 'B' ) ? 'bus' : 
            ( arg == 'A' ) ? 'airplane' : 
            ( arg == 'T' ) ? 'train' : 
            ( arg == 'C' ) ? 'car' : 
            ( arg == 'H' ) ? 'horse' : 
                             'feet' );
</cfscript>
<cfoutput>#vehicle#</cfoutput>

Ejemplo 2

editar
<cfscript>
price = ( product.hasPrice() ) ? product.getPrice() : "-";
writeOutput( "Precio del producto: " & price );
</cfscript>

Java, JSP

editar

En Java el operador ternario es también referido como el operador condicional y utiliza la misma sintaxis que los demás lenguajes basados en el lenguaje C. Por ejemplo, para verificar que una persona es mayor de edad, utilizaríamos lo siguiente:

   boolean mayor_de_edad = edad >= 18 ? true: false;

Remplazaria el siguiente código detallado:

 boolean mayor_de_edad;
 if(edad >= 18){
    mayor_de_edad = true;
 }else{
    mayor_de_edad = false;
 }

Para utilizar el operador ternario en JavaServer Pages, se puede incrustrar código de Java usando scriptlets. Esta manera no es recomendada, lo cual se sugiere usar bibliotecas de JSTL para obtener código más limpio y estructurado. Por ejemplo, para alternar el color de las filas en una tabla de HTML usando CSS, pudiéramos utilizar lo siguiente:

  <c:forEach list="${requestScope.miLista}" varStatus="contador"> 
      <tr class="${contador % 0 ? 'even' : 'odd'}">
         <td>Hola Mundo!!!</td>
      </tr>
  </c:forEach>

Perl, PHP

editar

Un constructor tradicional de if-else en Perl o PHP se escribiría así:

if ($a > $b) {
    $result = $a;
} else {
    $result = $b;
}

Reescrito con el operador ternario, se vería así:

$result = ($a > $b) ? $a : $b;

Desde la versión 5.3, PHP soporta una sintaxis del operador ternario. En esta forma, la condición es regresada a menos que la condición se evalúa como falsa:

 $variable = condicion ?: if false

Python

editar

Aunque se había demorado durante varios años por los desacuerdos sobre la sintaxis, un operador ternario para Python se aprobó como Python Enhancement Proposal 308 y se añadió a la versión 2.5 en septiembre de 2006. El operador ternario de Python difiere del común ?: en el orden de sus operandos. La forma general es:

valor_si_cierto if condición else valor_si_falso

Visual Basic .NET

editar

A pesar de que .NET no utiliza los operandos ?: se puede usar una implementación muy similar a la sentencia if...else.

Dim tiempo_de_apertura As Integer = IIf((dia = FIN_DE_SEMANA), 12, 9)
 
'sintaxis general es IIf(condicion, valor_si_cierto, valor_si_falso)

En el ejemplo anterior, IIF es una función, y no un operador ternario real. Como función, los valores de las tres partes se evalúan antes de que se produzca llamada de la función. Esto impuso limitaciones y en Visual Basic. NET 9.0, lanzado como Visual Studio 2008, un operador ternario real fue introducido usando como clave IF en vez de IIF. Esto permite que el siguiente código funcione:

Dim nombre As String = If(persona Is Nothing, "", persona.Nombre)

Usando IIF, persona.Nombre se evaluaría incluso si el valor de persona es nothing (nulo), causando una excepción. Con un verdadero operador ternario de cortocircuito, persona.Nombre sólo se evalúa si el valor de persona no es nulo.

Referencias

editar
  1. «BCPL Ternary operator (page 15)». BCPL Reference Manual. Archivado desde el original el 27 de febrero de 2008. 
  2. «Ternary Operators». Kwista, LLC. Archivado desde el original el 25 de abril de 2010. Consultado el 19 de abril de 2010. 

Enlaces externos

editar