Digamos que tengo un objeto:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
Quiero hacer un nuevo objeto con un subconjunto de sus propiedades.
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
¿Cómo puedo lograr esto?
javascript
Christian Schlensker
fuente
fuente
emo.slice
a primera vista.Respuestas:
Uso de la desestructuración de objetos y la taquigrafía de propiedades
De Philipp Kewisch:
fuente
let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
const { b, ...picked } = object
, crearíapicked
como{ a: 5, c: 7 }
. Ha especificado simplemente eliminar b. Sin embargo, su eslint probablemente se molestará por declarar una var que no está usando.Sugiero echar un vistazo a Lodash ; Tiene muchas funciones de gran utilidad.
Por ejemplo
pick()
, sería exactamente lo que buscas:violín
fuente
_.omit(elmo, ['voice'])
para devolver todo menosvoice
Si está utilizando ES6, hay una manera muy concisa de hacerlo mediante la desestructuración. La desestructuración le permite agregar fácilmente a los objetos usando una extensión, pero también le permite crear objetos de subconjuntos de la misma manera.
fuente
Si bien es un poco más detallado, puede lograr lo que todos los demás estaban recomendando subrayado / lodash durante 2 años, utilizando Array.prototype.reduce .
Este enfoque lo resuelve desde el otro lado: en lugar de tomar un objeto y pasarle nombres de propiedad para extraerlo, tome una matriz de nombres de propiedad y reduzca a un nuevo objeto.
Si bien es más detallado en el caso más simple, una devolución de llamada aquí es bastante útil, ya que puede cumplir fácilmente algunos requisitos comunes, por ejemplo, cambiar la propiedad 'color' a 'color' en el nuevo objeto, aplanar matrices, etc., cualquiera de Las cosas que debe hacer al recibir un objeto de un servicio / biblioteca y construir un nuevo objeto necesario en otro lugar. Si bien el subrayado / lodash son bibliotecas excelentes y bien implementadas, este es mi enfoque preferido para una menor dependencia del proveedor y un enfoque más simple y más consistente cuando mi lógica de creación de subconjuntos se vuelve más compleja.
editar: es7 versión de la misma:
editar: ¡Un buen ejemplo para curry también! Haga que una función 'pick' devuelva otra función.
Lo anterior es bastante similar al otro método, excepto que le permite construir un 'selector' sobre la marcha. p.ej
Lo que es especialmente interesante de este enfoque es que puede pasar fácilmente las 'elecciones' elegidas a cualquier cosa que tenga una función, por ejemplo
Array#map
:fuente
function showToy({ color, height }) {
, pondría solo lo que necesita en el alcance. Elreduce
enfoque tiene sentido principalmente cuando simplifica objetos para la serialización.const pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
fetch
), por lo que recomendaría agregar un comentario explicando el uso del operador de coma.ES6 desestructuración
La sintaxis de desestructuración permite desestructurar y recombinar un objeto, ya sea con parámetros de función o variables.
La limitación es que una lista de claves está predefinida, no se pueden enumerar como cadenas, como se menciona en la pregunta. La desestructuración se vuelve más complicada si una clave no es alfanumérica, por ejemplo
foo_bar
.La desventaja es que esto requiere duplicar una lista de claves, esto da como resultado un código detallado en caso de que una lista sea larga. Dado que la desestructuración de la sintaxis literal de objetos duplicados en este caso, una lista se puede copiar y pegar tal cual.
Lo bueno es que es una solución eficaz que es natural para ES6.
IIFE
Variables temporales
Una lista de cadenas
La lista arbitraria de claves seleccionadas consta de cadenas, según lo requiera la pregunta. Esto permite no predefinirlos y usar variables que contienen nombres clave, como
pick(obj, 'foo', someKey, ...moreKeys)
.Una línea se acorta con cada edición de JS.
ES5
ES6
O con operador de coma:
ES2019
ECMAScript 2017 tiene
Object.entries
yArray.prototype.includes
, ECMAScript 2019 tieneObject.fromEntries
, se pueden rellenar cuando sea necesario y facilitar la tarea:Un one-liner se puede reescribir como una función auxiliar similar a Lodash
pick
oomit
donde la lista de claves se pasa a través de argumentos:Una nota sobre las llaves faltantes
La principal diferencia entre la desestructuración y la función convencional similar a Lodash
pick
es que la desestructuración incluye claves recogidas inexistentes conundefined
valor en un subconjunto:Este comportamiento puede o no ser deseable. No se puede cambiar por la sintaxis de desestructuración.
Mientras que
pick
se puede cambiar para incluir claves faltantes iterando una lista de claves elegidas en su lugar:fuente
obj
variable sea una variable que almacene un objeto. Si su nombre de variable difiere, úselo en lugar deobj
.Object.keys(obj)
. Soñoliento.No hay nada como eso integrado en la biblioteca principal, pero puede usar la desestructuración de objetos para hacerlo ...
También podría escribir una función de utilidad hacerlo ...
Las bibliotecas como Lodash también tienen
_.pick()
.fuente
Estoy agregando esta respuesta porque ninguna de las respuestas utilizadas
Comma operator
.Es muy fácil con
destructuring assignment
y,
operadorCon una cierta mejora para la asignación de propiedades dinámicas, podría verse así:
fuente
'use strict'
). Me sale unReferenceError: a is not defined
.a
yc
: tenga cuidado de no sobrescribir aleatoriamente variables locales o globales según el contexto. (La respuesta aceptada evita este problema mediante el uso de dos variables locales en una función en línea, que queda fuera del alcance después de la ejecución inmediata.)Una solución mas:
Esto me parece mucho más legible que casi cualquier respuesta hasta ahora, ¡pero tal vez solo soy yo!
fuente
subset = {color: elmo.color, height: elmo.color}
, habría tenido al menos un ... bueno, quizás un centavo.Puedes usar Lodash también.
Complementando, digamos que tiene una serie de "elmo" s:
Si desea el mismo comportamiento, usando lodash, simplemente:
fuente
La desestructuración en variables dinámicamente nombradas es imposible en JavaScript como se discutió en esta pregunta .
Para establecer claves dinámicamente , puede usar la función reducir sin mutar el objeto de la siguiente manera:
a continuación se muestra una versión que usa reducción con un solo clon (actualización del valor inicial pasado para reducir).
fuente
Solución TypeScript:
La información de escritura incluso permite la finalización automática:
¡Crédito para definitivamente escrito para
U extends keyof T
truco!fuente
Utilice el
pick
método de la biblioteca lodash si ya lo está utilizando.https://lodash.com/docs/4.17.10#pick
fuente
Solución dinámica
Mostrar fragmento de código
fuente
Solo otra forma ...
Puede usar esta función con una matriz de objetos =)
fuente
Qué tal si:
fuente
false
(o falso). jsfiddle.net/nfAs8keys[i] in obj
.Esto funciona para mí en la consola de Chrome. ¿Algún problema con esto?
fuente
Asignación de desestructuración con propiedades dinámicas
Esta solución no solo se aplica a su ejemplo específico, sino que se aplica de manera más general:
Puede definir fácilmente
subset4
etc. para tener más propiedades en cuenta.fuente
Bueno viejo
Array.prototype.reduce
:esta respuesta usa el operador de coma mágico, también: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
si quieres ponerte realmente elegante, esto es más compacto:
Poniendo todo junto en una función reutilizable:
fuente
convertir argumentos a matriz
utilizar
Array.forEach()
para elegir la propiedadfuente
fuente
Tratar
fuente
Agregando mis 2 centavos a Ivan Nosov respuesta de :
En mi caso, necesitaba muchas claves para ser 'cortadas' del objeto, por lo que se está volviendo feo muy rápido y no es una solución muy dinámica:
Así que aquí hay una solución dinámica usando eval:
fuente
puede extender jquery si lo desea, aquí está el código de muestra para un segmento:
aquí está el violín para lo mismo: http://jsfiddle.net/w633z/
fuente