En Javascript, estoy tratando de tomar una matriz inicial de valores numéricos y contar los elementos dentro de ella. Idealmente, el resultado sería dos nuevas matrices, la primera que especifica cada elemento único y la segunda que contiene el número de veces que ocurre cada elemento. Sin embargo, estoy abierto a sugerencias sobre el formato de la salida.
Por ejemplo, si la matriz inicial era:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Luego se crearían dos nuevas matrices. El primero contendría el nombre de cada elemento único:
5, 2, 9, 4
El segundo contendría la cantidad de veces que ese elemento ocurrió en la matriz inicial:
3, 5, 1, 1
Debido a que el número 5 aparece tres veces en la matriz inicial, el número 2 aparece cinco veces y 9 y 4 aparecen una vez.
He buscado mucho una solución, pero nada parece funcionar, y todo lo que he probado ha resultado ser ridículamente complejo. ¡Cualquier ayuda sería apreciada!
Gracias :)
fuente
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
para lograr esto de la manera fácil.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
volvería3
a indicar que hay '3' cinco en la matriz.Respuestas:
Aqui tienes:
Demostración en vivo: http://jsfiddle.net/simevidas/bnACW/
fuente
O(N log(N))
y la ganancia elegancia no vale la penareduce
respuesta. Estaba a punto de presentar tal respuesta antes de ver que ya existía. Sin embargo, lacounts[num] = counts[num] ? counts[num]+1 : 1
respuesta también funciona (equivalente a laif(!result[a[i]])result[a[i]]=0
respuesta, que es más elegante pero menos fácil de leer); estas respuestas pueden modificarse para usar una versión "más agradable" del bucle for, quizás un for-loop de terceros, pero ignoré eso ya que los bucles for basados en índices estándar son lamentablemente los predeterminados.Puede usar un objeto para guardar los resultados:
Entonces, ahora su objeto de conteo puede decirle cuál es el conteo para un número particular:
Si desea obtener una variedad de miembros, simplemente use las
keys()
funcionesfuente
Object.keys()
función solo es compatible con IE9 +, FF4 +, SF5 +, CH6 +, pero Opera no lo admite. Creo que el mayor show stopper aquí es IE9 + .counts[num] = (counts[num] || 0) + 1
. De esa manera, solo tiene que escribircounts[num]
dos veces en lugar de tres veces en esa línea allí.[5, "5"]
simplemente dirá que tienes"5"
dos veces. O contar instancias de algunos objetos diferentes solo te dirá que hay muchos[object Object]
. Etc. etc.fuente
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Si usa subrayado o lodash, esto es lo más simple:
Tal que:
Como señalaron otros, puede ejecutar las funciones
_.keys()
y_.values()
en el resultado para obtener solo los números únicos y sus ocurrencias, respectivamente. Pero en mi experiencia, el objeto original es mucho más fácil de manejar.fuente
No use dos matrices para el resultado, use un objeto:
Entonces
result
se verá así:fuente
¿Qué tal una opción ECMAScript2015?
Este ejemplo pasa la matriz de entrada al
Set
constructor creando una colección de valores únicos . La sintaxis extendida luego expande estos valores en una nueva matriz para que podamos llamarmap
y traducir esto en una matriz bidimensional de[value, count]
pares, es decir, la siguiente estructura:La nueva matriz se pasa al
Map
constructor dando como resultado un objeto iterable :Lo mejor de un
Map
objeto es que conserva los tipos de datos, es deciraCount.get(5)
, volverá3
peroaCount.get("5")
volveráundefined
. También permite que cualquier valor / tipo actúe como clave, lo que significa que esta solución también funcionará con una variedad de objetos.Mostrar fragmento de código
fuente
Set
usa referencias de objetos para la unicidad y no ofrece API para comparar objetos "similares" . Si desea utilizar este enfoque para tal tarea, necesitaría alguna función de reducción intermedia que garantice una variedad de instancias únicas. No es el más eficiente, pero preparé un ejemplo rápido aquí .Creo que esta es la forma más simple de contar las ocurrencias con el mismo valor en la matriz.
fuente
a.filter(value => !value).length
con la nueva sintaxis jsSolución ES6 de una línea. Tantas respuestas usando el objeto como mapa pero no puedo ver a nadie usando un mapa real
Úselo
map.keys()
para obtener elementos únicosUse
map.values()
para obtener los sucesosUse
map.entries()
para obtener los pares [elemento, frecuencia]fuente
fuente
Si prefiere un solo revestimiento.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Editar (6/12/2015) : La explicación de adentro hacia afuera. countMap es un mapa que mapea una palabra con su frecuencia, en la cual podemos ver la función anónima. Lo que reduce es aplicar la función con argumentos como todos los elementos de la matriz y countMap que se pasa como el valor de retorno de la última llamada a la función. El último parámetro ({}) es el valor predeterminado de countMap para la primera llamada de función.
fuente
;
,{
y}
. ... OKAY. Creo que con esa definición de un trazador de líneas podemos escribir El juego de la vida de Conway como un "trazador de líneas".La versión ES6 debería ser mucho más simple (otra solución de una línea)
Un mapa en lugar de un objeto simple que nos ayuda a distinguir diferentes tipos de elementos, o de lo contrario todo el conteo se basa en cadenas
fuente
Si está usando guión bajo, puede seguir la ruta funcional
entonces tu primer arreglo es
y la segunda matriz es
la mayor parte de esto usará de forma predeterminada las funciones nativas de JavaScript si están disponibles
demostración: http://jsfiddle.net/dAaUU/
fuente
Según la respuesta de @adamse y @pmandell (que voté positivamente ), en ES6 puede hacerlo en una línea :
||
para reducir el tamaño del código y hacerlo más legible.Se puede usar para contar caracteres :
fuente
|| 0
(r,k)=>{r[k]=(r[k]||0)+1;return r}
Aquí hay algo ligero y fácil para los ojos ...
Editar: Y como quieres todas las ocurrencias ...
fuente
Así que así es como lo haría con algunas de las características más nuevas de JavaScript:
Primero, reduzca la matriz a uno
Map
de los recuentos:Al usar a
Map
, su matriz inicial puede contener cualquier tipo de objeto, y los recuentos serán correctos. Sin aMap
, algunos tipos de objetos te darán recuentos extraños. Consulte losMap
documentos para obtener más información sobre las diferencias.Esto también se podría hacer con un objeto si todos sus valores son símbolos, números o cadenas:
O un poco más elegante de una manera funcional sin mutación, utilizando la sintaxis de desestructuración y propagación de objetos:
En este punto, puede usar el
Map
objeto o para sus recuentos (y el mapa es directamente iterable, a diferencia de un objeto), o convertirlo en dos matrices.Para el
Map
:O para el objeto:
fuente
fuente
Map
, ya que evitará el encasillamiento que hace el uso de un número como clave de objeto (conversión como cadena).const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
Puede obteneranswer.keys()
las claves yanswer.values()
los valores como matrices.[...answer]
le dará una gran matriz con todas las claves / valores como matrices 2d.Solución ES6 con reducción (fija):
fuente
Editar 2020 : esta es una respuesta bastante antigua (nueve años). Extender al nativo
prototype
siempre generará discusión . Aunque creo que el programador es libre de elegir su propio estilo de programación, aquí hay un enfoque (más moderno) del problema sin extenderloArray.prototype
:La vieja respuesta (2011): podría extender
Array.prototype
, así:Mostrar fragmento de código
fuente
Mi solución con ramda:
Enlace a REPL.
fuente
Solución usando un mapa con O (n) complejidad de tiempo.
Demostración: http://jsfiddle.net/simevidas/bnACW/
fuente
Hay una manera mucho mejor y más fácil de hacerlo
ramda.js
. Código de muestra aquíconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
countBy la documentación está en la documentaciónfuente
Usando MAP puede tener 2 matrices en la salida: una que contiene las ocurrencias y la otra que contiene el número de ocurrencias.
fuente
Mira el código a continuación.
fuente
Prueba esto:
fuente
Estaba resolviendo un problema similar en codewars e ideé la siguiente solución que funcionó para mí.
Esto proporciona el recuento más alto de un entero en una matriz y también el entero mismo. Creo que también se puede aplicar a la matriz de cadenas.
Para ordenar correctamente las cuerdas, retire el
function(a, b){return a-b}
interior de lasort()
porciónfuente
Aquí hay una manera de contar las ocurrencias dentro de una matriz de objetos. También coloca el contenido de la primera matriz dentro de una nueva matriz para ordenar los valores de modo que el orden en la matriz original no se interrumpa. Luego, se utiliza una función recursiva para recorrer cada elemento y contar la propiedad de cantidad de cada objeto dentro de la matriz.
fuente
fuente
fuente
Esta pregunta tiene más de 8 años y muchas, muchas respuestas no tienen realmente en cuenta ES6 y sus numerosas ventajas.
Quizás sea aún más importante pensar en las consecuencias de nuestro código para la recolección de basura / gestión de memoria cada vez que creamos matrices adicionales, hacemos copias dobles o triples de matrices o incluso convertimos matrices en objetos. Estas son observaciones triviales para pequeñas aplicaciones, pero si la escala es un objetivo a largo plazo, piense detenidamente en esto.
Si solo necesita un "contador" para tipos de datos específicos y el punto de partida es una matriz (por lo tanto, supongo que desea una lista ordenada y aprovechar las muchas propiedades y métodos que ofrecen las matrices), puede simplemente iterar a través de matriz1 y completar array2 con los valores y el número de ocurrencias para estos valores encontrados en array1.
Tan sencillo como eso.
Ejemplo de clase simple SimpleCounter (ES6) para programación orientada a objetos y diseño orientado a objetos
fuente
finalList
no tiene ninguna razón para ser una matriz, y esto no tiene ventajas sobre hacerlo correctamente.Aquí hay un método clásico de la vieja escuela para contar matrices.
Puede ordenarlo primero si desea un resultado alfabético, pero si desea preservar el orden en que se ingresaron los datos, inténtelo. Los bucles anidados pueden ser un poco más lentos que algunos de los otros métodos en esta página.
fuente