Una línea para tomar algunas propiedades del objeto en ES 6

Resuelto kirilloid asked hace 10 años • 13 respuestas

¿Cómo se puede escribir una función que solo toma unos pocos atributos de la manera más compacta en ES6?

Se me ocurrió una solución usando desestructuración + literal de objeto simplificado, pero no me gusta que la lista de campos se repita en el código.

¿Existe una solución aún más sencilla?

(v) => {
    let { id, title } = v;
    return { id, title };
}
kirilloid avatar Aug 28 '14 23:08 kirilloid
Aceptado

Aquí hay algo más delgado, aunque no evita repetir la lista de campos. Utiliza "desestructuración de parámetros" para evitar la necesidad del vparámetro.

({id, title}) => ({id, title})

(Vea un ejemplo ejecutable en esta otra respuesta ).

La solución de @EthanBrown es más general. Aquí hay una versión más idiomática que usa Object.assigny propiedades calculadas (la [p]parte):

function pick(o, ...props) {
    return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}

Si queremos preservar los atributos de las propiedades, como configurablelos captadores y definidores, y al mismo tiempo omitir las propiedades no enumerables, entonces:

function pick(o, ...props) {
    var has = p => o.propertyIsEnumerable(p),
        get = p => Object.getOwnPropertyDescriptor(o, p);

    return Object.defineProperties({},
        Object.assign({}, ...props
            .filter(prop => has(prop))
            .map(prop => ({prop: get(props)})))
    );
}
 avatar Aug 28 '2014 17:08

No creo que haya alguna manera de hacerlo mucho más compacto que tu respuesta (o la del torazburo), pero esencialmente lo que intentas hacer es emular la operación de Underscorepick . Sería bastante fácil volver a implementar eso en ES6:

function pick(o, ...fields) {
    return fields.reduce((a, x) => {
        if(o.hasOwnProperty(x)) a[x] = o[x];
        return a;
    }, {});
}

Entonces tienes una práctica función reutilizable:

var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
Ethan Brown avatar Sep 14 '2014 16:09 Ethan Brown

El truco para resolver esto de una sola línea es invertir el enfoque adoptado: en lugar de comenzar desde el objeto original orig, uno puede comenzar desde las claves que desea extraer.

Luego, usar Array#reduceuno puede almacenar cada clave necesaria en el objeto vacío que se pasa como initialValuepara dicha función.

Al igual que:

const orig = {
  id: 123456789,
  name: 'test',
  description: '…',
  url: 'https://…',
};

const filtered = ['id', 'name'].reduce((result, key) => { result[key] = orig[key]; return result; }, {});

console.log(filtered); // Object {id: 123456789, name: "test"}
Expandir fragmento

alternativamente...

const filtered = ['id', 'name'].reduce((result, key) => ({
    ...result, 
    [key]: orig[key] 
}), {});

console.log(filtered); // Object {id: 123456789, name: "test"}
Bramus avatar Jan 20 '2017 14:01 Bramus