Digamos que eu tenho um objeto:
{
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
}
Eu quero criar outro objeto filtrando o objeto acima para que eu tenha algo parecido.
{
item1: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
}
Estou procurando uma maneira limpa de fazer isso usando o Es6, para que os operadores espalhados estejam disponíveis para mim.
filter
ecmascript-6
29er
fonte
fonte
Respostas:
Se você tiver uma lista de valores permitidos, poderá mantê-los facilmente em um objeto usando:
Isso usa:
Object.keys
para listar todas as propriedadesraw
(os dados originais) e, em seguida,Array.prototype.filter
para selecionar as chaves presentes na lista de permissões, usandoArray.prototype.includes
para garantir que eles estejam presentesArray.prototype.reduce
para criar um novo objeto apenas com as propriedades permitidas.Isso fará uma cópia superficial com as propriedades permitidas (mas não copiará as próprias propriedades).
Você também pode usar o operador de propagação de objetos para criar uma série de objetos sem alterá-los (obrigado a rjerue por mencionar isso ):
Para fins de trivialidades, se você quiser remover os campos indesejados dos dados originais (o que eu não recomendaria, pois envolve algumas mutações feias), você pode inverter a
includes
verificação da seguinte forma:Estou incluindo este exemplo para mostrar uma solução baseada em mutação, mas não sugiro usá-la.
fonte
Array.prototype.includes
não faz parte do ES6. É introduzido no ECMAScript 2016 (ES7).Se você concorda com o uso da sintaxe ES6, acho que a maneira mais limpa de fazer isso, conforme observado aqui e aqui, é:
Agora,
newData
contém:Ou, se você tiver a chave armazenada como uma sequência:
No último caso,
[key]
é convertido em,item2
mas como você está usando umaconst
atribuição, é necessário especificar um nome para a atribuição._
representa um valor descartável.De forma geral:
Isso não apenas reduz sua operação a uma linha, mas também não exige que você saiba quais são as outras chaves (aquelas que você deseja preservar).
fonte
_
representa um valor descartável" de onde isso vem? Primeira vez que eu vê-lo_
é simplesmente um nome de variável válido que pode ser usado em JS, mas como é praticamente sem nome, ele realmente não deve ser usado dessa maneira se você deseja transmitir a intenção. Portanto, foi adotado como uma maneira de denotar uma variável com a qual você não se importa. Aqui está uma discussão mais aprofundada sobre isso: stackoverflow.com/questions/11406823/...filter
ereduce
._
não importa, é apenas um nome de variável, você pode renomeá-lo para o que quiseromit
função do lodash : lodash.com/docs/4.17.10#omit ou uma das outras soluções fornecidas aqui.A maneira mais limpa de encontrar é usando o Lodash # pick
fonte
Nada que não tenha sido dito antes, mas para combinar algumas respostas a uma resposta geral do ES6:
fonte
Apenas mais uma solução em uma linha do Modern JS sem bibliotecas externas .
Eu estava jogando com o recurso " Destructuring ":
fonte
var myNewRaw = (({ item1, item3}) => ({ item1, item3 }))(raw);
Problema de sintaxeAgora você pode torná-lo mais curto e simples usando o método Object.fromEntries (verifique o suporte ao navegador):
leia mais sobre: Object.fromEntries
fonte
Você pode adicionar um genérico
ofilter
(implementado com genéricooreduce
) para filtrar facilmente os objetos da mesma maneira que as matrizes -Podemos vê-lo trabalhando aqui -
Verifique os resultados em seu próprio navegador abaixo -
Mostrar snippet de código
Essas duas funções podem ser implementadas de várias maneiras. Eu escolhi anexar ao
Array.prototype.reduce
interior,oreduce
mas você poderia facilmente escrever tudo do zerofonte
oreduce
, o primeiroacc
é sombreado em.reduce(acc, k)
, e emofilter
oo
é sombreado -oreduce
é chamado com uma variável chamadao
, bem como - qual é qual?ofilter
variávelo
é sombreada, mas sempre aponta para a mesma entrada var; é por isso que está sombreado aqui, porque é o mesmo - o acumulator (acc
) também é sombreado porque mostra mais claramente como os dados se movem através do lambda;acc
nem sempre é a mesma ligação , mas sempre representa o estado persistente atual do resultado computacional que desejamos retornarFoi assim que fiz recentemente:
fonte
Object.assign == ...
Você poderia escreverconst dummyObj = { ...obj }
econst target = { ...dummyObj }
. Além disso, o último não é de todo necessário, pois você poderá trabalhar diretamente com o dummyObj posteriormente.ok, que tal esse one-liner
fonte
As respostas aqui são definitivamente adequadas, mas são um pouco lentas, porque exigem um loop na lista de permissões para todas as propriedades do objeto. A solução abaixo é muito mais rápida para grandes conjuntos de dados, porque apenas percorre a lista de permissões uma vez:
fonte
Pegando carona na resposta do ssube .
Aqui está uma versão reutilizável.
Para chamá-lo, use
O lado bom das funções de seta do ES6 é que você não precisa passar
allowed
como parâmetro.fonte
Você pode fazer algo assim:
Isso funciona, mas não é muito claro, além da
with
declaração não ser recomendada ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with ).fonte
Uma solução mais simples sem o uso
filter
pode ser alcançada com, emObject.entries()
vez deObject.keys()
fonte
Existem muitas maneiras de conseguir isso. A resposta aceita usa uma abordagem Keys-Filter-Reduce, que não é a que apresenta melhor desempenho.
Em vez disso, usar um
for...in
loop para percorrer as chaves de um objeto ou percorrer as chaves permitidas e depois compor um novo objeto é ~ 50% mais eficiente a .uma. Consulte jsPerf para obter os benchmarks de um caso de uso simples. Os resultados serão diferentes com base nos navegadores.
fonte
Você pode remover uma chave específica do seu objeto
fonte
fonte
Maneira simples! Para fazer isso.
fonte
Outra solução usando o
Array.reduce
método "novo" :Demonstração neste violino ...
Mas eu gosto da solução nesta resposta aqui que está usando e :
Object.fromEntries
Array.filter
Array.includes
Demonstração neste violino ...
fonte
OK, e quanto a isso:
e chame assim:
fonte
Essa função filtrará um objeto com base em uma lista de chaves, é mais eficiente que a resposta anterior, pois não precisa usar Array.filter antes de chamar reduzir. então é O (n) em oposição a O (n + filtrado)
fonte
Durante o loop, não retorne nada quando determinadas propriedades / chaves forem encontradas e continue com o restante:
fonte
Estou surpreso como ninguém sugeriu isso ainda. É super limpo e muito explícito sobre quais chaves você deseja manter.
Ou se você quiser um liner sujo:
fonte
Outra abordagem seria usar
Array.prototype.forEach()
comoEle inclui valores apenas das chaves disponíveis nos dados brutos, impedindo a adição de dados indesejados.
fonte
Essa seria a minha solução:
fonte