Include or sum key/value type elements in a javascript array

Asked

Viewed 240 times

0

I need to include in an array objects of the key/value type with information coming from the database, but if the key already exists in the array, the value must be added to what already exists. Development in Angular

/*A informação do banco vem assim:
  variavel[
  item1:10,
  item2:5]
*/
minhaVariavel: any[] = []

metodo(){
 this.dao.readRegisters().subscribe(data => {
    data.docs.forEach(d => {
      const info = d.data()

  //Antes de fazer o push preciso saber se a chave da nova info já existe na minhaVariavel, se existir o valor deve ser somado ao que já existe, senão ele deve ser inserido. (não sei se consegui ser claro)

  this.minhaVariavel.push(info.informacao)
  })
 })
}

1 answer

0


There’s more than one way to do this, I’ll show you one using a little functional paradigm.

// simulei essa variável como o resultado que vem do banco
const retornoBanco: any[] = [{ item: 10 }, { item2: 20 }, { item: 5 }, { item6: 25 }];
// aqui como exemplo considerei que já existia um valor no array
const minhaVariavel: any[] = [{ item: 3 }];

// aqui fiz uma redução e transformei um array em um objeto com chaves e valores
const retornoReduzido = retornoBanco.reduce((objeto, atual) => {
    // será utilizado caso a chave não exista
    const valorInicial = 0;
    // percorre todas as chaves do objeto atual e adiciona ao objeto de retorno,
    // se as informações do banco não estiverem agrupadas, as instruções abaixo
    // irão agrupá-las
    Object.keys(atual).forEach(
        (key) => (objeto[key] = (objeto[key] || valorInicial) + atual[key])
    );

    // retorna o objeto com as chaves adicionadas para a próxima etapa
    // da redução
    return objeto;
}, {} /* inicialização do objeto que será retornado */);

// percorre os itens existentes em minhaVariavel e incrementa
// de acordo com as informações de mesma chave que vieram do banco
minhaVariavel.forEach((elemento) => {
    Object.keys(elemento).forEach((key) => {
        if (retornoReduzido[key]) {
            elemento[key] += retornoReduzido[key];
            // remove chave-valor do retorno do banco para adicionar
            // somente os novos itens nas instruções finais
            delete retornoReduzido[key];
        }
    });
});

// percorre os retornos do banco que não existiam na minhaVariavel
// adicionando-os em minhaVariavel
Object.keys(retornoReduzido).forEach((key) =>
    minhaVariavel.push({ [key]: retornoReduzido[key] })
);

I left the code commented speaking what each part does, I recommend that you see How to create a Minimum, Complete and Verifiable example, so that in your next questions you have a more assertive answer.

References:

reduce

foreach

Object.Keys()

  • Returns this error on the wideVariable.push({ [key]: returnReduced[key] }): The argument of type '{ [x: string]: any; }' is not attributable to the parameter of type '{ item: number; }'. The property 'item' is missing in type '{ [x: string]: any; }',)

  • What you can understand from the mistake is that the minhaVariavel is an array of { item: number }, I mean, you have to own the property item, but from what I understood in your example, this item would be dynamic, coming with different keys.

  • Exactly, dynamic. I copied your code in order to understand, before implementing, but then it made that mistake there

  • I thought I had already ported to your code typescript, I put the type of the variable to any[], now it should work

  • Thank you very much, show!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.