Original article: How to Count Objects in an Array

Saber como iterar rápidamente un arreglo y contar objetos es decepcionantemente simple. El atributo length te dirá el número total de valores del arreglo pero, ¿y si solamente quieres contar esos valores basados en ciertas condiciones?

Por ejemplo, imagina que tienes un arreglo como este:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

Y tú solamente quieres contar el número de objetos con el estado puesto en '0'.

Como con casi todo en programación, hay unas formas de hacer esto. Veremos algunos métodos comunes abajo.

Usar un bucle for

Probablemente la manera más fácil sería declarar una variable contador, recorrer a través del arreglo, e iterar el contador solamente si el estado es igual a '0':

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

let contador = 0;
for (let i = 0; i < almacenamiento.length; i++) {
  if (almacenamiento[i].status === '0') contador++;
}

console.log(contador); // 6

Podrías simplificarlo un poco usando un bucle for...of:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

let contador = 0;
for (const obj of almacenamiento) {
  if (obj.estado === '0') contador++;
}

console.log(contador); // 6

También, podrías crear una función para hacer lo mismo si tienes otros arreglos de objetos para contar de manera condicional:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

function estadoDelContador(entradas) {
  let contador = 0;
  for (const entrada of entradas) {
    if (entrada.estado === '0') contador += 1;
  }
  return contador;
}

estadoDelContador(almacenamiento); // 6

Usar métodos del arreglo

JavaScript incluye un montón de métodos útiles cuando se trabaja con arreglos. Cada uno puede ser encadenado a un arreglo y pasarle diferentes parámetros con los cuales trabajar mientras se itera a través de los elementos del arreglo.

Los dos que veremos son filter() y reduce().

filter()

El método filter hace sólo eso - itera sobre cada elemento del arreglo y filtra todos los elementos que no cumplen la(s) condicion(es) que proveíste. Luego regresa un nuevo array con todos los elementos que retornaron true basado en tu(s) condicion(es).

Por ejemplo:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.filter(function(item){
  if (item.estado === 0) {
    return true;
  } else {
    return false;
  }
});

/*
[
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' }
] 
*/

Ahora que has filtrado el objeto con estado: 1, solamente llama el atributo length del nuevo arreglo para tener el recuento total de los objetos con estado: '1':

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.filter(function(item){
  if (item.estado === 0) {
    return true;
  } else {
    return false;
  }
}).length; // 6

Pero esto puede ser acortado un montón con la sintaxis de ES6:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.filter(item => item.estado === '0').length; // 6

reduce()

Imagina al método reduce como una navaja suiza - es extramadamente flexible, y te permite tomar un arreglo como input y transformarlo en casi cualquier cosa. Aún mejor, como filter(), este método regresa un nuevo arreglo, dejando el original intacto.

Para nuestros fines, queremos tomar un arreglo, examinar su contenido, y producir un nuevo número. Aquí hay una simple manera de hacerlo:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.reduce((contador, obj) => {
  if (obj.estado === '0') contador += 1
  return contador;
}, 0); // 6

Podrías simplificarlo aún más allá usando sintaxis de ES6 y un operador ternario:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.reduce((contador, obj) => obj.estado === '0' ? contador += 1 : contador, 0); // 6

E inclusive un poco más usando destructuración de objetos:

const almacenamiento = [
  { dato: '1', estado: '0' },
  { dato: '2', estado: '0' },
  { dato: '3', estado: '0' },
  { dato: '4', estado: '0' },
  { dato: '5', estado: '0' },
  { dato: '6', estado: '0' },
  { dato: '7', estado: '1' },
];

const recuento = almacenamiento.reduce((contador, { estado }) => estado === '0' ? contador += 1 : contador, 0); // 6

Así que esos son algunas maneras de recorrer elementos de un arreglo y contarlos de manera condicional. Ahora ve y cuenta con confianza!