Me gustaría crear un objeto con un miembro agregado condicionalmente. El enfoque simple es:
var a = {};
if (someCondition)
a.b = 5;
Ahora, me gustaría escribir un código más idiomático. Estoy intentando:
a = {
b: (someCondition? 5 : undefined)
};
Pero ahora, b
es un miembro de a
cuyo valor es undefined
. Este no es el resultado deseado.
¿Hay alguna solución útil?
Actualizar
Busco una solución que pueda manejar el caso general con varios miembros.
a = {
b: (conditionB? 5 : undefined),
c: (conditionC? 5 : undefined),
d: (conditionD? 5 : undefined),
e: (conditionE? 5 : undefined),
f: (conditionF? 5 : undefined),
g: (conditionG? 5 : undefined),
};
javascript
viebel
fuente
fuente
a.b
, la recuperacióna.b
volvería deundefined
todos modos.in
se utiliza el operador.Respuestas:
En Javascript puro, no puedo pensar en nada más idiomático que su primer fragmento de código.
Sin embargo, si el uso de la biblioteca jQuery no está descartado, entonces $ .extend () debería cumplir con sus requisitos porque, como dice la documentación:
Por lo tanto, puedes escribir:
Y obtenga los resultados que espera (si
conditionB
es asífalse
, entoncesb
no existiráa
).fuente
Creo que @InspiredJW lo hizo con ES5, y como señaló @trincot, usar es6 es un mejor enfoque. Pero podemos agregar un poco más de azúcar, utilizando el operador de propagación y la evaluación lógica Y de cortocircuito:
fuente
Null/Undefined Are Ignored
, no dice quefalse
se ignore. Los transpiladores pueden permitir esto en este momento, pero ¿es compatible? Lo siguiente debería ser{...someCondition ? {b: 5} : null}
pero no es tan compacto.Object.assign
y tiene menor prioridad que el operador &&. Ignora el valor sin propiedad (booleano, nulo, indefinido, número) y agrega todas las propiedades del objeto después del...
lugar. recuerde que el&&
operador devuelve el valor correcto si es verdadero o falso de lo contrario. por lo que sisomeCondition
es cierto,{b : 5}
será pasado al...
operador, lo que resulta en la adición de la propiedadb
quea
con valor5
. essomeCondition
falso, sefalse
pasará al...
operador. resultando en nada agregado. Es inteligente. Me encanta.Con EcmaScript2015 puede usar
Object.assign
:Mostrar fragmento de código
Algunas observaciones:
Object.assign
modifica el primer argumento en el lugar, pero también devuelve el objeto actualizado: para que pueda usar este método en una expresión más grande que manipule aún más el objeto.null
usted podría pasarundefined
o{}
, con el mismo resultado. Incluso podría proporcionar en su0
lugar, porque los valores primitivos están envueltos, yNumber
no tienen propiedades propias enumerables .Aún más conciso
Teniendo además el segundo punto, se podría acortar la siguiente manera (como @Jamie tiene cabo puntas), como valores Falsy no tienen propiedades enumerables propias (
false
,0
,NaN
,null
,undefined
,''
, exceptodocument.all
):Mostrar fragmento de código
fuente
Demo en vivo:
fuente
El uso de sintaxis extendida con booleano (como se sugiere aquí) no es una sintaxis válida. Spread solo se puede usar con iterables .
Sugiero lo siguiente:
fuente
{...false}
{...false}
es una sintaxis válidaCopyDataProperties
se realiza en el valor (false
en este caso). Esto implica boxear una primitiva (secciones 7.3.23, 7.1.13). El enlace que tiene a MDN menciona esta "excepción" entre paréntesis.¿Qué pasa con el uso de propiedades de objetos mejorados y solo establece la propiedad si es verdadera, por ejemplo:
Entonces, si no se cumple la condición, no crea la propiedad preferida y, por lo tanto, puede descartarla. Ver: http://es6-features.org/#ComputedPropertyNames
ACTUALIZACIÓN: es aún mejor seguir el enfoque de Axel Rauschmayer en su artículo de blog sobre agregar condicionalmente entradas dentro de literales y matrices de objetos ( http://2ality.com/2017/04/conditional-literal-entries.html ):
Me ayudó mucho.
fuente
false
clave adicional . Por ejemplo,{[true && 'a']: 17, [false && 'b']: 42}
es{a:17, false: 42}
...isConditionTrue() && { propertyName: 'propertyValue' }
más simplificado
fuente
Si el objetivo es que el objeto parezca autónomo y esté dentro de un conjunto de llaves, puede intentar esto:
fuente
Si desea hacer este lado del servidor (sin jquery), puede usar lodash 4.3.0:
Y esto funciona usando lodash 3.10.1
fuente
Espero que esta sea la forma más eficiente de agregar una entrada en función de la condición. Para obtener más información sobre cómo agregar entradas condicionalmente dentro de un objeto literal.
fuente
[...condition?'':['item']]
esto agregará un elemento de cadena en la matrizEsto ha sido respondido durante mucho tiempo, pero mirando otras ideas se me ocurrió una derivada interesante:
Asigne valores indefinidos a la misma propiedad y elimínelos después
Cree su objeto utilizando un constructor anónimo y siempre asigne miembros indefinidos al mismo miembro ficticio que elimine al final. Esto le dará una sola línea (no demasiado compleja, espero) por miembro + 1 línea adicional al final.
fuente
Puede agregar todos sus valores indefinidos sin condiciones y luego usar
JSON.stringify
para eliminarlos todos:fuente
Yo haría esto
Editado con una versión de código de línea
fuente
a = undefined
. Se puede cambiar fácilmente conreturn { b: undefined };
: /return {};
enelse
partea = condition ? {b:5} : undefined;
Usando la biblioteca lodash, puedes usar _.omitBy
Esto resulta útil cuando tiene solicitudes que son opcionales
fuente
Creo que su primer enfoque para agregar miembros condicionalmente está perfectamente bien. Realmente no estoy de acuerdo con no querer tener un miembro
b
dea
un valor deundefined
. Es bastante simple agregar unundefined
cheque con el uso de unfor
bucle con elin
operador. Pero de todos modos, podría escribir fácilmente una función para filtrarundefined
miembros.También puede usar el
delete
operador para editar el objeto en su lugar.fuente
Envolver en un objeto
Algo como esto es un poco más limpio
Envolver en una matriz
O si desea utilizar el método de Jamie Hill y tener una lista muy larga de condiciones, debe escribir la
...
sintaxis varias veces. Para hacerlo un poco más limpio, puede envolverlos en una matriz y luego usarlosreduce()
para devolverlos como un solo objeto.O usando la
map()
funciónfuente
Esta es la solución más sucinta que se me ocurre:
fuente
Defina una var por
let
y simplemente asigne una nueva propiedadAhora el
msg
convertidoEn mi opinión, esta es una solución muy simple y fácil.
fuente
Usando la biblioteca lodash, puedes usar _.merge
false
y la condición C estrue
, entoncesa = { c: 5 }
true
, entoncesa = { b: 4, c: 5 }
false
, entoncesa = {}
fuente
lodash@^4.0.0
.undefined
están siendo incluidos en mi caso.