Respuestas:
Muy simple:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);y los detalles de implementación pueden discutirse en su interior.
[ esta respuesta está un poco anticuada: lee las ediciones ]
Saluda a tus amigos: mapy filtery reducey forEachy everyetc.
(Solo ocasionalmente escribo for-loops en javascript, porque falta el alcance a nivel de bloque, por lo que debe usar una función como el cuerpo del bucle de todos modos si necesita capturar o clonar su índice o valor de iteración. For-loops son más eficientes en general, pero a veces necesita un cierre).
La forma más legible:
[....].filter(x => x==2).length
(Podríamos haber escrito en su .filter(function(x){return x==2}).lengthlugar)
Lo siguiente es más eficiente en espacio (O (1) en lugar de O (N)), pero no estoy seguro de cuánto beneficio / penalidad podría pagar en términos de tiempo (no más que un factor constante desde su visita cada elemento exactamente una vez):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(Si necesita optimizar este fragmento de código en particular, un bucle for podría ser más rápido en algunos navegadores ... puede probar cosas en jsperf.com).
Luego puede ser elegante y convertirlo en una función prototipo:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Me gusta esto:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
También puede pegar la antigua técnica regular de bucle for (ver otras respuestas) dentro de la definición de propiedad anterior (nuevamente, eso probablemente sería mucho más rápido).
Edición 2017 :
Vaya, esta respuesta se ha vuelto más popular que la respuesta correcta. En realidad, solo usa la respuesta aceptada. Si bien esta respuesta puede ser linda, los compiladores js probablemente no optimizan (o no pueden debido a las especificaciones) tales casos. Entonces realmente deberías escribir un bucle for simple:
Object.defineProperties(Array.prototype, {
count: {
value: function(query) {
/*
Counts number of occurrences of query in array, an integer >= 0
Uses the javascript == notion of equality.
*/
var count = 0;
for(let i=0; i<this.length; i++)
if (this[i]==query)
count++;
return count;
}
}
});
Podría definir una versión .countStrictEq(...)que utilizara la ===noción de igualdad. ¡La noción de igualdad puede ser importante para lo que estás haciendo! (por ejemplo [1,10,3,'10'].count(10)==2, porque números como '4' == 4 en javascript ... por lo tanto lo llama .countEqo .countNonstricthace hincapié en que usa el ==operador).
También considere usar su propia estructura de datos de múltiples conjuntos (por ejemplo, como la de Python ' collections.Counter') para evitar tener que contar en primer lugar.
class Multiset extends Map {
constructor(...args) {
super(...args);
}
add(elem) {
if (!this.has(elem))
this.set(elem, 1);
else
this.set(elem, this.get(elem)+1);
}
remove(elem) {
var count = this.has(elem) ? this.get(elem) : 0;
if (count>1) {
this.set(elem, count-1);
} else if (count==1) {
this.delete(elem);
} else if (count==0)
throw `tried to remove element ${elem} of type ${typeof elem} from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)`;
// alternatively do nothing {}
}
}
Manifestación:
> counts = new Multiset([['a',1],['b',3]])
Map(2) {"a" => 1, "b" => 3}
> counts.add('c')
> counts
Map(3) {"a" => 1, "b" => 3, "c" => 1}
> counts.remove('a')
> counts
Map(2) {"b" => 3, "c" => 1}
> counts.remove('a')
Uncaught tried to remove element a of type string from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)
nota al margen: Sin embargo, si todavía quisiera la forma de programación funcional (o una línea de un solo uso sin anular el prototipo Array), podría escribirlo más brevemente hoy en día como [...].filter(x => x==2).length. Si le importa el rendimiento, tenga en cuenta que si bien este es asintóticamente el mismo rendimiento que el ciclo for (tiempo O (N)), puede requerir memoria adicional O (N) (en lugar de memoria O (1)) porque casi ciertamente genera una matriz intermedia y luego cuenta los elementos de esa matriz intermedia.
array.reduce(function(total,x){return x==value? : total+1 : total}, 0)
[...].reduce(function(total,x){return x==2 ? total+1 : total}, 0)
const count = (list) => list.filter((x) => x == 2).length. Luego úselo llamando a count(list)donde la lista es una matriz de números. También puede hacer const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthpara contar instancias de crazyValue en la matriz de objetos. Tenga en cuenta que es una coincidencia exacta para la propiedad.
Actualización de ES6 a JS:
Tenga en cuenta que siempre debe usar triples iguales: ===para obtener una comparación correcta:
// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]
// Functional filter with an Arrow function
array.filter(x => x === 2).length // -> 3
La siguiente función de flecha unánime (función lambda) en JS:
(x) => {
const k = 2
return k * x
}
puede simplificarse a esta forma concisa para una sola entrada:
x => 2 * x
donde returnestá implícito
2017: si alguien todavía está interesado en la pregunta, mi solución es la siguiente:
const arrayToCount = [1, 2, 3, 5, 2, 8, 9, 2];
const result = arrayToCount.filter(i => i === 2).length;
console.log('number of the found elements: ' + result);
Si está usando lodash o subrayado, el método _.countBy proporcionará un objeto de totales agregados ingresados por cada valor en la matriz. Puede convertir esto en una línea si solo necesita contar un valor:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Esto también funciona bien en matrices de números. La frase para su ejemplo sería:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
La forma más extraña en que puedo pensar en hacer esto es:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Dónde:
Mi sugerencia, use un tiempo o for loop ;-)
No usar un bucle generalmente significa entregar el proceso a algún método que sí use un bucle.
Aquí hay una forma en que nuestro codificador de odio de bucle puede satisfacer su odio, a un precio:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
También puede llamar repetidamente indexOf, si está disponible como método de matriz, y mover el puntero de búsqueda cada vez.
Esto no crea una nueva matriz y el bucle es más rápido que forEach o filter.
Podría hacer una diferencia si tienes un millón de miembros a los que mirar.
function countItems(arr, what){
var count= 0, i;
while((i= arr.indexOf(what, i))!= -1){
++count;
++i;
}
return count
}
countItems(a,2)
/* returned value: (Number)
3
*/
String(a).match(/2/g).length + 1, aunque tenga cuidado con esto o su implementación no funcionará bien con dos dígitos.
La mayoría de las soluciones publicadas que utilizan funciones de matriz como el filtro están incompletas porque no están parametrizadas.
Aquí va una solución con la que el elemento a contar se puede establecer en tiempo de ejecución.
function elementsCount(elementToFind, total, number){
return total += number==elementToFind;
}
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(elementsCount.bind(this, elementToFind), 0);
La ventaja de este enfoque es que podría cambiar fácilmente la función para contar, por ejemplo, el número de elementos mayores que X.
También puede declarar la función reducir en línea
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(function (elementToFind, total, number){
return total += number==elementToFind;
}.bind(this, elementToFind), 0);
var elementToFind=2; ... function (elementToFind, total, number){ return total += number==elementToFind; }.bind(this, elementToFind) ...es más difícil de leer y no da ventaja sobre solo ... (acc, x) => acc += number == 2.... Sin embargo, me gusta su uso de en +=lugar de acc + (number == 2). Sin embargo, se siente como una sintaxis injustificada HACK.
Realmente, ¿por qué necesitarías mapo filterpara esto?
reducenació para este tipo de operaciones:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
¡Eso es! (si item==valen cada iteración, se agregará 1 al acumulador count, como truese resolverá 1).
Como una función:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
O bien, adelante y extienda sus matrices:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
Es mejor envolverlo en función:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
Aquí hay una forma ES2017 + de obtener los recuentos de todos los elementos de la matriz en O (N):
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] += 1) : 1;
});
Opcionalmente, también puede ordenar la salida:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log (countSorted) para su matriz de ejemplo:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Creo que lo que buscas es un enfoque funcional
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' es la condición, reemplácela por la tuya.
count = arr.filter(elem => elem === 'a').lengthocount = arr.filter(elem => {return elem === 'a'}).length
Soy un fanático de la función de reducción de js array.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
De hecho, si realmente quieres ponerte elegante, puedes crear una función de conteo en el prototipo de matriz. Entonces puedes reutilizarlo.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Entonces hazlo
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Solución por recursión
function count(arr, value) {
if (arr.length === 1) {
return arr[0] === value ? 1 : 0;
} else {
return (arr.shift() === value ? 1 : 0) + count(arr, value);
}
}
count([1,2,2,3,4,5,2], 2); // 3
filter, reduceo una simple forLoop, y también, más costosa cuando se mira el rendimiento, pero sigue siendo una excelente manera de hacerlo con recurrencia. Mi único cambio es: creo que sería mejor crear una función y agregar un filtro dentro para copiar la matriz y evitar una mutación de la matriz original, luego usar el recursivo como una función interna.
var arrayCount = [1,2,3,2,5,6,2,8];
var co = 0;
function findElement(){
arrayCount.find(function(value, index) {
if(value == 2)
co++;
});
console.log( 'found' + ' ' + co + ' element with value 2');
}
Haría algo así:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
Cree un nuevo método para la clase Array en el archivo de nivel central y úselo en todo su proyecto.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Use esto en cualquier parte de su proyecto:
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Aquí hay una línea en javascript.
(v === 2)en la matriz, devolviendo una matriz de unos y ceros.[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
El resultado es 3.
Dependiendo de cómo quieras ejecutarlo:
const reduced = (array, val) => { // self explanatory
return array.filter((element) => element === val).length;
}
console.log(reduced([1, 2, 3, 5, 2, 8, 9, 2], 2));
// 3
const reducer = (array) => { // array to set > set.forEach > map.set
const count = new Map();
const values = new Set(array);
values.forEach((element)=> {
count.set(element, array.filter((arrayElement) => arrayElement === element).length);
});
return count;
}
console.log(reducer([1, 2, 3, 5, 2, 8, 9, 2]));
// Map(6) {1 => 1, 2 => 3, 3 => 1, 5 => 1, 8 => 1, …}
Puede usar la propiedad de longitud en la matriz de JavaScript:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2