Tengo una matriz:
[1, 2, 3, 5, 2, 8, 9, 2]
Me gustaría saber cuántos 2
s hay en la matriz.
¿Cuál es la forma más elegante de hacerlo en JavaScript sin bucle con for
bucle?
javascript
Leem
fuente
fuente
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:
map
yfilter
yreduce
yforEach
yevery
etc.(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:
(Podríamos haber escrito en su
.filter(function(x){return x==2}).length
lugar)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):
(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:
Me gusta esto:
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:
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.countEq
o.countNonstrict
hace 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.Manifestación:
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.fuente
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 acount(list)
donde la lista es una matriz de números. También puede hacerconst count = (list) => list.filter((x) => x.someProp === 'crazyValue').length
para 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:La siguiente función de flecha unánime (función lambda) en JS:
puede simplificarse a esta forma concisa para una sola entrada:
donde
return
está implícitofuente
2017: si alguien todavía está interesado en la pregunta, mi solución es la siguiente:
fuente
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:
Esto también funciona bien en matrices de números. La frase para su ejemplo sería:
fuente
La forma más extraña en que puedo pensar en hacer esto es:
Dónde:
Mi sugerencia, use un tiempo o for loop ;-)
fuente
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:
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.
fuente
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.
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
fuente
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 deacc + (number == 2)
. Sin embargo, se siente como una sintaxis injustificada HACK.Realmente, ¿por qué necesitarías
map
ofilter
para esto?reduce
nació para este tipo de operaciones:[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
¡Eso es! (si
item==val
en cada iteración, se agregará 1 al acumuladorcount
, comotrue
se resolverá1
).Como una función:
O bien, adelante y extienda sus matrices:
fuente
Es mejor envolverlo en función:
fuente
Aquí hay una forma ES2017 + de obtener los recuentos de todos los elementos de la matriz en O (N):
Opcionalmente, también puede ordenar la salida:
console.log (countSorted) para su matriz de ejemplo:
fuente
Creo que lo que buscas es un enfoque funcional
elem === 'a' es la condición, reemplácela por la tuya.
fuente
count = arr.filter(elem => elem === 'a').length
ocount = arr.filter(elem => {return elem === 'a'}).length
Soy un fanático de la función de reducción de js array.
De hecho, si realmente quieres ponerte elegante, puedes crear una función de conteo en el prototipo de matriz. Entonces puedes reutilizarlo.
Entonces hazlo
fuente
Solución por recursión
fuente
filter
,reduce
o una simpleforLoop
, 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.Haría algo así:
fuente
Cree un nuevo método para la clase Array en el archivo de nivel central y úselo en todo su proyecto.
Use esto en cualquier parte de su proyecto:
fuente
Aquí hay una línea en javascript.
(v === 2)
en la matriz, devolviendo una matriz de unos y ceros.El resultado es
3
.fuente
Dependiendo de cómo quieras ejecutarlo:
fuente
Puede usar la propiedad de longitud en la matriz de JavaScript:
fuente