javascript - ¿Hay una mejor manera de escribir v = (v == 0? 1: 0);





variables coding-style toggle (25)


Si debe ser el número entero 1 o 0, entonces la forma en que lo está haciendo está bien, aunque no se necesitan paréntesis. Si estos a son para ser utilizados como booleanos, entonces solo puedes hacer:

v = !v;

Quiero cambiar una variable entre 0 y 1. Si es 0 quiero establecerlo en 1, de lo contrario, si es 1, quiero establecerlo en 0

Esta es una operación tan fundamental que escribo tan a menudo que me gustaría investigar la forma más corta y clara de hacerlo. Aquí está mi mejor hasta ahora:

v = (v == 0 ? 1 : 0);

¿Puedes mejorar esto?

Edit: la pregunta es cómo escribir la declaración anterior en la menor cantidad de caracteres y al mismo tiempo mantener la claridad. ¿Cómo es esto 'no es una pregunta real'? Esto no pretendía ser un ejercicio de código de golf, aunque se han obtenido algunas respuestas interesantes de personas que se acercan a él como golf, es agradable ver que el golf se utiliza de una manera constructiva y estimulante.




Simplemente puede utilizar:

v = 1 - v;

Por supuesto, esto supone que la variable se inicializa correctamente, es decir, que solo tiene el valor 0 o 1.

Otro método es más corto pero utiliza un operador menos común:

v ^= 1;

Editar:

Para ser claro; Nunca abordé esta pregunta como código de golf, solo para encontrar una forma corta de hacer la tarea sin utilizar trucos oscuros como los efectos secundarios de los operadores.




No sé por qué quieres construir tus propios booleanos? Me gustan las sintaxis funky, pero ¿por qué no escribir código comprensible?

Este no es el más corto / rápido, pero el más claro (y legible para todos) es utilizar el conocido estado if / else:

if (v === 0)
{
  v = 1;
}
else
{
  v = 0;
}

Si quieres ser realmente claro, debes usar booleanos en lugar de números para esto. Son lo suficientemente rápidos para la mayoría de los casos. Con los booleanos, puedes usar esta sintaxis, que ganará en corto:

v = !v;



en general, cuando necesite alternar entre dos valores, simplemente puede restar el valor actual de la suma de los dos valores de alternancia:

    0,1 -> v = 1 - v
    1,2 -> v = 3 - v
    4,5 -> v = 9 - v 



v=!v;

trabajará para v = 0 yv = 1; y alternar el estado;




Para resumir otra respuesta, un comentario y mi propia opinión, sugiero combinar dos cosas:

  1. Usa una función para el interruptor
  2. Dentro de esta función usar una implementación más legible.

Aquí está la función que podría colocar en una biblioteca o tal vez envolverla en un complemento para otro marco de Javascript.

function inv(i) {
  if (i == 0) {
    return 1
  } else {
    return 0;
  }
}

Y el uso es simplemente:

v = inv(v);

Las ventajas son:

  1. Sin duplicación de código
  2. Si usted o alguien vuelve a leer esto en el futuro, entenderá su código en un tiempo mínimo.



Si solo hay dos valores, como en este caso (0, 1), creo que es inútil usar int. Más bien ir para booleano y trabajar en bits. Sé que estoy asumiendo, pero en caso de alternar entre dos estados, el booleano parece ser la opción ideal.




Bueno, como sabemos, en javascript solo esa comparación booleana también le dará el resultado esperado.

v = v == 0es decir, es suficiente para eso.

A continuación se muestra el código para eso:

var v = 0; 
alert("if v  is 0 output: "+ (v == 0) );

setTimeout(function(){
v = 1; 
alert("if v  is 1 Output: "+ (v == 0) );
}, 1000);

JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/

Espero que esto te ayude :)




Ya que este es JavaScript, podemos usar el unario +para convertir a int:

v = +!v;

Esto hará lógico NOTel valor de v(dando truesi v == 0o falsesi v == 1). Luego convertimos el valor booleano devuelto en su representación entera correspondiente.




Lo haría más explícito.

¿Qué significa v ?

Por ejemplo, cuando v es algún estado. Crear un estado de objeto. En DDD un objeto de valor.

Implementar la lógica en este objeto de valor. Luego puede escribir su código de una manera más funcional que sea más legible. El cambio de estado se puede hacer creando un nuevo estado basado en el estado actual. Tu sentencia / lógica if se encapsula en tu objeto, que puedes probar. Un valueObject siempre es inmutable, por lo que no tiene identidad. Así que para cambiar su valor tienes que crear uno nuevo.

Ejemplo:

public class Status
{
    private readonly int _actualValue;
    public Status(int value)
    {
        _actualValue = value;
    }
    public Status(Status status)
    {
        _actualValue = status._actualValue == 0 ? 1 : 0; 
    }

    //some equals method to compare two Status objects
}

var status = new Status(0);

Status = new Status(status);



Podrías escribir una función para ella y usarla como:

v = inv(v)




v = Número (! v)

Se escribirá convertir el valor booleano invertido a número, que es la salida deseada.




define una matriz {1,0}, establece v en v [v], por lo tanto v con un valor de 0 se convierte en 1, y vica versa.




Una más: v=++v%2

(en C sería simple ++v%=2 )

PD. Sí, ya sé que se trata de una doble asignación, pero esto es solo una reescritura sin formato del método de C (que no funciona como está, porque el operador de preincremento JS no devuelve el valor l.




Solo para patadas: v = Math.pow(v-1,v) también alterna entre 1 y 0.




Otra forma de su solución original:

v = Number(v == 0);

EDITAR: Gracias a TehShrike y Guffa por señalar el error en mi solución original.




Otra forma creativa de hacerlo, con vser igual a cualquier valor, siempre regresará 0o1

v = !!v^1;



Dado que 0 es un valor false y 1 es un valor true .

v = (v ? 0 : 1);

Si estás feliz de usar true y false lugar de números

v = !v;

o si deben ser números:

v = +!v; /* Boolean invert v then cast back to a Number */



Esto falta:

v = [1, 0][v];

Funciona también como round robin:

v = [2, 0, 1][v]; // 0 2 1 0 ...
v = [1, 2, 0][v]; // 0 1 2 0 ...
v = [1, 2, 3, 4, 5, 0][v]; // 0 1 2 3 4 5 ...
v = [5, 0, 1, 2, 3, 4][v]; // 0 5 4 3 2 1 0 ...

O

v = {0: 1, 1: 0}[v];

El encanto de la última solución, funciona con todos los demás valores también.

v = {777: 'seven', 'seven': 777}[v];



Las líneas como v = 1 - v , o v ^= 1 o v= +!v harán el trabajo, pero constituyen lo que yo llamaría hacks. Estas no son hermosas líneas de código, sino trucos baratos para lograr el efecto deseado. 1 - v no comunica "cambiar el valor entre 0 y 1". Esto hace que su código sea menos expresivo e introduce un lugar (aunque pequeño) donde otro desarrollador tendrá que analizar su código.

Tener en su lugar una función como v = toggle(v) comunica la intención a la vista más rápida.







v = (v + 1) % 2 y si necesita desplazarse por más valores, simplemente cambie 2 por (n + 1) . Digamos que necesita completar el ciclo 0,1,2 solo v = (v + 1) % 3 .




Lista de soluciones

Hay tres soluciones que me gustaría proponer. Todos ellos convierten cualquier valor a 0 (si es 1 , true , etc.) o 1 (si es 0 , false , null , etc.):

  • v = 1*!v
  • v = +!v
  • v = ~~!v

y uno adicional, ya mencionado, pero inteligente y rápido (aunque funciona solo para 0 sy 1 s):

  • v = 1-v

Solución 1

Puedes usar la siguiente solución:

v = 1*!v

Esto primero convertirá el entero al booleano opuesto ( 0 a True y cualquier otro valor a False ), luego lo tratará como un entero cuando se multiplique por 1 . Como resultado, 0 se convertirá en 1 y cualquier otro valor en 0 .

Como prueba, vea este jsfiddle y proporcione los valores que desea probar: jsfiddle.net/rH3g5/

Los resultados son los siguientes:

  • -123 se convertirá a entero 0 ,
  • -10 se convertirá a entero 0 ,
  • -1 se convertirá a entero 0 ,
  • 0 se convertirá a entero 1 ,
  • 1 se convertirá a entero 0 ,
  • 2 se convertirá a entero 0 ,
  • 60 se convertirá a entero 0 ,

Solucion 2

Como mblase75 señaló, jAndy tenía alguna otra solución que funciona como la mía:

v = +!v

También hace primero el valor booleano desde el valor original, pero usa + lugar de 1* para convertirlo en entero. El resultado es exactamente el mismo, pero la notación es más corta.

Solucion 3

El otro enfoque es utilizar el operador ~~ :

v = ~~!v

Es bastante infrecuente y siempre se convierte en entero desde booleano.




Si no te importa otra posibilidad que no sea 1:

v = v ? 0 : 1;

En el caso anterior, v terminará siendo 1 si v es 0, falso, indefinido o nulo. Tenga cuidado al utilizar este tipo de enfoque: v será 0 incluso si v es "hola mundo".




Esto se ve mejor, proporciona legibilidad, pero es más lento que otros métodos.

$.each(selectData, function(i, option)
{
    $("<option/>").val(option.id).text(option.title).appendTo("#selectBox");
});

Si desea velocidad, la forma más rápida (¡probada!) Es esta, utilizando una matriz, no la concatenación de cadenas, y utilizando solo una llamada adjunta.

auxArr = [];
$.each(selectData, function(i, option)
{
    auxArr[i] = "<option value='" + option.id + "'>" + option.title + "</option>";
});

$('#selectBox').append(auxArr.join(''));




javascript variables coding-style toggle