How to know how many times an object appeared in the array

Asked

Viewed 124 times

3

I would like to know how to return the amount of times each object appeared in an array, for example:

Entree:

array1 = [
  {nome: joao},
  {nome: maria},
  {nome: joao},
  {nome: carlos},
  {nome: joao},
  {nome: carlos},
]

Exit:

array2 = [
  {nome: joao, quantidade: 3},
  {nome: maria, quantidade: 1},
  {nome: carlos, quantidade: 2}
]

My code:

for(var h in array1){
  array3.push({
    [array1[h].nome]: false
  })
}
for(var i in array1){
  var count = 1
  var nome = array1[i].nome
  for(var k in array3){
     if(array3[k][nome]==false){
        for(var j=i+1; j<array1.length; j++){
          if(array1[i].nome==array1[j].nome){
            count++
            total+=count
            array3[k][nome] = true
          }         
        }
        array2.push({
          nome: nome,
          quantidade: count
        })
        break
      }
    }   
  }

2 answers

5


We can create a function that takes two arguments:

  • The array object;
  • The property we’ll use to count.

Something like that:

function countObjects(input, prop) {
  // Criamos um objeto que vai armazenar o número de cada objeto.
  const counter = {}

  for (const obj of input) {
    // Nome da iteração atual:
    const name = obj[prop]

    if (counter.hasOwnProperty(name)) {
      // Caso o nome já exista no contador, incremente o número em 1.
      counter[name]++
    } else {
      // Caso contrário, inicialize em 1.
      counter[name] = 1
    }
  }

  return Object.entries(counter).map(([key, value]) => ({
    [prop]: key,
    quantidade: value
  }))
}

Performing in practice:

const array = [
  { nome: 'joao' },
  { nome: 'maria' },
  { nome: 'joao' },
  { nome: 'carlos' },
  { nome: 'joao' },
  { nome: 'carlos' }
]

function countObjects(input, prop) {
  // Criamos um objeto que vai armazenar o número de cada objeto.
  const counter = {}

  for (const obj of input) {
    // Nome da iteração atual:
    const name = obj[prop]

    if (counter.hasOwnProperty(name)) {
      // Caso o nome já exista no contador, incremente o número em 1.
      counter[name]++
    } else {
      // Caso contrário, inicialize em 1.
      counter[name] = 1
    }
  }

  return Object.entries(counter).map(([key, value]) => ({
    [prop]: key,
    quantidade: value
  }))
}

// Irá verificar quantos objetos existem, contando a proriedade "nome":
const output = countObjects(array, 'nome')

// Mostra o output:
console.log(output)

Resource reference used in the code:


Bonus: Rewrite crazy using reduce:

const data = [
  { name: 'Daniel' },
  { name: 'Louis' },
  { name: 'Alice' },
  { name: 'Louis' },
  { name: 'Alice' },
  { name: 'Petter' },
  { name: 'Louis' }
]

function countObjects(input, prop) {
  return Object.entries(
    input.reduce(
      (a, c) => ({
        ...a,
        [c[prop]]: a.hasOwnProperty(c[prop]) ? ++a[c[prop]] : 1
      }),
      {}
    )
  ).map(([key, count]) => ({
    [prop]: key,
    count
  }))
}

console.log(countObjects(data, 'name'))

  • 1

    Excellent answer, I always try to answer in the simplest possible way, because I do not know for sure the knowledge on the subject of who asked the question, but, your answer demonstrates a great knowledge in language. + 1.

2

You can reach the expected result using the method filter:

let array1 = [
  {nome: 'joao'},
  {nome: 'maria'},
  {nome: 'joao'},
  {nome: 'carlos'},
  {nome: 'joao'},
  {nome: 'carlos'},
];

let nomeJoao = array1.filter(function(elemento, index) {
  let joao = elemento.nome == 'joao';
  return joao;
})

let nomeMaria = array1.filter(function(elemento) {
  let maria = elemento.nome == 'maria';
  return maria;
})

let nomeCarlos = array1.filter(function(elemento) {
  let carlos = elemento.nome == 'carlos';
  return carlos;
})

let array2 = [
  {nome: nomeJoao[0].nome, quantidade: nomeJoao.length},
  {nome: nomeMaria[0].nome, quantidade: nomeMaria.length},
  {nome: nomeCarlos[0].nome, quantidade: nomeCarlos.length}
]

console.log(array2);

  • How could I leave dynamic, because the list of names can appear new names. I tried it here and it can return the values but returns for example: Joao: 3, Joao:2 and Joao:1, because the is unable to jump to the next one if he has already counted Jonathan. How do I do this with the filter

  • I edited the answer, basically you will call the variable that contains the filter by passing the .name to always catch the name related to the quantity.

Browser other questions tagged

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