One-liner para tirar algumas propriedades do object em ES 6

Como se pode escrever uma function, que leva apenas alguns atributos de maneira mais compacta no ES6?

Eu vim com solução usando desestruturação + literal de object simplificado, mas eu não gosto que a lista de campos seja repetida no código.

Existe uma solução ainda mais elegante?

(v) => { let { id, title } = v; return { id, title }; } 

Aqui está algo mais elegante, embora não evite repetir a lista de campos. Ele usa “desestruturação de parâmetro” para evitar a necessidade do parâmetro v .

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

A solução do @ EthanBrown é mais geral. Aqui está uma versão mais idiomática dele que usa Object.assign e propriedades calculadas (a parte [p] ):

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

Se quisermos preservar os atributos das propriedades, como configurable getters e setters, omitindo as propriedades não enumeráveis, então:

 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)}))) ); } 

Eu não acho que haja alguma maneira de torná-lo muito mais compacto do que a sua resposta (ou do torazburo), mas essencialmente o que você está tentando fazer é emular a operação de pick do Underscore . Seria fácil reimplementar isso no ES6:

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

Então você tem uma function reutilizável:

 var stuff = { name: 'Thing', color: 'blue', age: 17 }; var picked = pick(stuff, 'name', 'age'); 

O truque para resolver isso como um one-liner é inverter a abordagem adotada: em vez de partir do orig original do object, pode-se começar a partir das chaves que ele deseja extrair.

Usando Array#reduce é possível armazenar cada chave necessária no object vazio que é passado como initialValue para a function mencionada.

Igual a:

 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"} 

A proposta de propriedades de repouso / propagação de object do TC39 tornará isso muito elegante:

 let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; z; // { a: 3, b: 4 } 

(Tem a desvantagem de criar as variables x e y que você pode não precisar.)

Uma solução um pouco mais curta usando o operador vírgula:

 const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {}) 

Eu tenho semelhante à solução de Ethan Brown, mas ainda mais curto – pick function. Outra function pick2 é um pouco mais longa (e mais lenta), mas permite renomear propriedades de maneira semelhante ao ES6.

 const pick = (o, ...props) => props.reduce((r, p) => p in o ? {...r, [p]: o[p]} : r, {}) const pick2 = (o, ...props) => props.reduce((r, expr) => { const [p, np] = expr.split(":").map( e => e.trim() ) return p in o ? {...r, [np || p]: o[p]} : r }, {}) 

Aqui está o exemplo de uso:

 const d = { a: "1", c: "2" } console.log(pick(d, "a", "b", "c")) // -> { a: "1", c: "2" } console.log(pick2(d, "a: x", "b: y", "c")) // -> { x: "1", c: "2" } 

Eu solicitei esse sollution, mas não sabia se as chaves propostas estavam disponíveis. Então, eu respondi @torazaburo e melhorei para o meu caso de uso:

 function pick(o, ...props) { return Object.assign({}, ...props.map(prop => { if (o[prop]) return {[prop]: o[prop]}; })); } // Example: var person = { name: 'John', age: 29 }; var myObj = pick(person, 'name', 'sex'); // { name: 'John' } 
    Intereting Posts