Aqui está algo mais simples, embora não evite repetir a lista de campos. Ele usa "destruição de parâmetros" para evitar a necessidade do v
parâmetro.
({id, title}) => ({id, title})
(Veja um exemplo executável nesta outra resposta ).
A solução da @ EthanBrown é mais geral. Aqui está uma versão mais idiomática, que usa Object.assign
e calcula as propriedades (a [p]
parte):
function pick(o, ...props) {
return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}
Se queremos preservar os atributos das propriedades, como configurable
e getters e setters, além de omitir 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)})))
);
}
Object.assign
; ES6 é como uma árvore de Natal com tantos presentes sob ela ainda estou encontrando presentes meses após o feriadofilter(...).map(prop => ({[prop]: get(prop)})))
?pick()
implementação, você também pode fazer algo como:return props.reduce((r, prop) => (r[prop] = o[prop], r), {})
undefined
. Às vezes isso importa. Fora isso, boa ideia.Não acho que exista uma maneira de torná-lo muito mais compacto do que sua resposta (ou do torazburo), mas essencialmente o que você está tentando fazer é imitar a
pick
operação do Underscore . Seria fácil reimplementar isso no ES6:Então você tem uma função útil e reutilizável:
fonte
pick
função uma vez, e você pode escolher quantas propriedades quiser e não as duplicará.hasOwnProperty
? Se os campos são selecionados manualmente, atéin
parece ser mais apropriado; embora eu optasse por omitir completamente a verificação e apenas deixá-los usar como padrãoundefined
.O truque para resolver isso como uma linha é mudar a abordagem adotada: em vez de começar pelo objeto original
orig
, pode-se começar pelas chaves que eles desejam extrair.O uso de
Array#reduce
um pode armazenar cada chave necessária no objeto vazio que é passado como ainitialValue
função para a referida função.Igual a:
fonte
Uma solução um pouco mais curta usando o operador de vírgula:
fonte
pick
funções neste tópico:pick({ name: 'John', age: 29, height: 198 }, 'name', 'age')
A proposta de propriedades de descanso / propagação de objetos do TC39 tornará isso muito liso:
(Ele tem a desvantagem de criar as variáveis
x
ey
que você pode não precisar.)fonte
omit
, mas nãopick
let { a, b } as z = { x: 1, y: 2, a: 3, b: 4 }
Você pode usar a desestruturação de objetos para descompactar propriedades do objeto existente e atribuí-las a variáveis com nomes diferentes - campos de um novo objeto inicialmente vazio.
fonte
ES6 era a especificação mais recente no momento em que a pergunta foi escrita. Conforme explicado nesta resposta , a seleção de teclas é significativamente menor no ES2019 do que no ES6:
fonte
Atualmente, existe uma proposta simplificada para melhorar a sintaxe abreviada de objetos do JavaScript, o que permitiria "escolher" as propriedades nomeadas sem repetição:
Infelizmente, a proposta não parece chegar a lugar nenhum tão cedo. Última edição em julho de 2017 e ainda um rascunho no Estágio 0 , sugerindo que o autor tenha se esquecido ou esquecido.
ES5 e versões anteriores (modo não estrito)
A abreviação possível e concisa que posso pensar envolve um recurso de linguagem antiga que ninguém mais usa:
with
as instruções são proibidas no modo estrito, tornando essa abordagem inútil para 99,999% do JavaScript moderno. É uma pena, porque esse é o único uso meio decente que encontrei para owith
recurso. 😀fonte
Eu tenho semelhante à solução de Ethan Brown, mas ainda mais curta -
pick
função. Outra funçãopick2
é um pouco mais longa (e mais lenta), mas permite renomear propriedades da maneira semelhante à do ES6.Aqui está o exemplo de uso:
fonte
Eu exigia essa solução, mas não sabia se as chaves propostas estavam disponíveis. Então, peguei a resposta @torazaburo e melhorei para o meu caso de uso:
fonte
inspirado na abordagem de redução de https://stackoverflow.com/users/865693/shesek :
uso:
pick({ model : 'F40', manufacturer: 'Ferrari', productionYear: 1987 }, 'model', 'productionYear')
resulta em:{model: "F40", productionYear: 1987}
fonte