En Javascript, j'essaie de prendre un tableau initial de valeurs numériques et de compter les éléments qu'il contient. Idéalement, le résultat serait deux nouveaux tableaux, le premier spécifiant chaque élément unique et le second contenant le nombre de fois où chaque élément se produit. Cependant, je suis ouvert aux suggestions sur le format de la sortie.
Par exemple, si le tableau initial était:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Ensuite, deux nouveaux tableaux seraient créés. Le premier contiendrait le nom de chaque élément unique:
5, 2, 9, 4
La seconde contiendrait le nombre de fois où cet élément s'est produit dans le tableau initial:
3, 5, 1, 1
Étant donné que le nombre 5 se produit trois fois dans le tableau initial, le nombre 2 se produit cinq fois et 9 et 4 apparaissent tous les deux une fois.
J'ai beaucoup cherché une solution, mais rien ne semble fonctionner, et tout ce que j'ai essayé moi-même s'est révélé ridiculement complexe. Toute aide serait appréciée!
Merci :)
la source
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
pour y parvenir la voie facile.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
retournerait3
pour indiquer qu'il y a «3» cinq dans le tableau.Réponses:
Voici:
Démo en direct: http://jsfiddle.net/simevidas/bnACW/
la source
O(N log(N))
et le gain d'élégance n'en vaut pas la peinereduce
réponse. J'étais sur le point de soumettre une telle réponse avant de voir qu'elle existait déjà. Néanmoins, lacounts[num] = counts[num] ? counts[num]+1 : 1
réponse fonctionne également (équivalente à laif(!result[a[i]])result[a[i]]=0
réponse, qui est plus élégante mais moins facile à lire); ces réponses peuvent être modifiées pour utiliser une version "plus agréable" de la boucle for, peut-être une boucle for tierce, mais j'ai en quelque sorte ignoré cela puisque les boucles for basées sur l'index standard sont malheureusement la valeur par défaut.Vous pouvez utiliser un objet pour contenir les résultats:
Donc, maintenant votre objet count peut vous dire quel est le compte pour un nombre particulier:
Si vous souhaitez obtenir un tableau de membres, utilisez simplement les
keys()
fonctionsla source
Object.keys()
fonction n'est prise en charge que dans IE9 +, FF4 +, SF5 +, CH6 + mais Opera ne la prend pas en charge. Je pense que le plus gros bouchon d'exposition est IE9 + .counts[num] = (counts[num] || 0) + 1
. De cette façon, vous n'avez qu'à écrirecounts[num]
deux fois au lieu de trois fois sur cette seule ligne.[5, "5"]
dira simplement que vous avez"5"
deux fois. Ou compter des exemples d'objets différents va juste vous dire qu'il y en a beaucoup[object Object]
. Etc. etc.la source
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Si vous utilisez un trait de soulignement ou un lodash, c'est la chose la plus simple à faire:
Tel que:
Comme indiqué par d'autres, vous pouvez ensuite exécuter les fonctions
_.keys()
et_.values()
sur le résultat pour obtenir uniquement les nombres uniques et leurs occurrences, respectivement. Mais d'après mon expérience, l'objet d'origine est beaucoup plus facile à gérer.la source
N'utilisez pas deux tableaux pour le résultat, utilisez un objet:
Cela
result
ressemblera alors à:la source
Que diriez-vous d'une option ECMAScript2015.
Cet exemple transmet le tableau d'entrée au
Set
constructeur en créant une collection de valeurs uniques . La syntaxe étendue étend ensuite ces valeurs dans un nouveau tableau afin que nous puissions appelermap
et traduire cela en un tableau bidimensionnel de[value, count]
paires - c'est-à-dire la structure suivante:Le nouveau tableau est ensuite passé au
Map
constructeur résultant en un objet itérable :La grande chose à propos d'un
Map
objet est qu'il préserve les types de données - c'est-à-direaCount.get(5)
qu'il reviendra3
maisaCount.get("5")
qu'il reviendraundefined
. Il permet également à n'importe quelle valeur / type d'agir comme une clé, ce qui signifie que cette solution fonctionnera également avec un tableau d'objets.Afficher l'extrait de code
la source
Set
utilise des références d'objet pour l'unicité et n'offre aucune API pour la comparaison d' objets "similaires" . Si vous souhaitez utiliser cette approche pour une telle tâche, vous aurez besoin d'une fonction de réduction intermédiaire qui garantit un tableau d'instances uniques. Ce n'est pas le plus efficace mais j'ai rassemblé un exemple rapide ici .Je pense que c'est la façon la plus simple de compter les occurrences avec la même valeur dans le tableau.
la source
a.filter(value => !value).length
avec la nouvelle syntaxe jsSolution ES6 à une ligne. Tant de réponses utilisant l'objet comme carte mais je ne vois personne utiliser une vraie carte
Utilisation
map.keys()
pour obtenir des éléments uniquesUtilisation
map.values()
pour obtenir les occurrencesUtilisez
map.entries()
pour obtenir les paires [élément, fréquence]la source
la source
Si vous préférez une doublure simple.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Edit (6/12/2015) : L'explication de l'intérieur. countMap est une carte qui mappe un mot avec sa fréquence, dont nous pouvons voir la fonction anonyme. Ce que fait réduire est d'appliquer la fonction avec des arguments comme tous les éléments du tableau et countMap étant transmis comme valeur de retour du dernier appel de fonction. Le dernier paramètre ({}) est la valeur par défaut de countMap pour le premier appel de fonction.
la source
;
,{
et}
. ... D'ACCORD. Je pense qu'avec cette définition d'un liner, nous pouvons écrire Game of Life de Conway comme un "oneliner".La version ES6 devrait être beaucoup plus simple (une autre solution d'une ligne)
Une carte au lieu d'un simple objet nous aidant à distinguer différents types d'éléments, ou bien tous les comptages sont basés sur des chaînes
la source
Si vous utilisez le soulignement, vous pouvez suivre la route fonctionnelle
donc votre premier tableau est
et le deuxième tableau est
la plupart de ceux-ci seront par défaut des fonctions natives javascript si elles sont disponibles
démo: http://jsfiddle.net/dAaUU/
la source
Sur la base des réponses de @adamse et @pmandell (que j'ai voté), dans ES6, vous pouvez le faire en une seule ligne :
||
pour réduire la taille du code et le rendre plus lisible.Il peut être utilisé pour compter les caractères :
la source
|| 0
(r,k)=>{r[k]=(r[k]||0)+1;return r}
Voici juste quelque chose de léger et facile pour les yeux ...
Edit: Et puisque vous voulez toutes les occurrences ...
la source
Voici donc comment je le ferais avec certaines des dernières fonctionnalités javascript:
Tout d'abord, réduisez le tableau à l'un
Map
des nombres:En utilisant a
Map
, votre tableau de départ peut contenir n'importe quel type d'objet et les nombres seront corrects. SansMap
, certains types d'objets vous donneront d'étranges dénombrements. Voir laMap
documentation pour plus d'informations sur les différences.Cela peut également être fait avec un objet si toutes vos valeurs sont des symboles, des nombres ou des chaînes:
Ou légèrement plus sophistiqué de manière fonctionnelle sans mutation, en utilisant la syntaxe de déstructuration et de propagation d'objet:
À ce stade, vous pouvez utiliser le
Map
objet ou pour vos décomptes (et la carte est directement itérable, contrairement à un objet), ou la convertir en deux tableaux.Pour le
Map
:Ou pour l'objet:
la source
la source
Map
place, car cela évitera la conversion en caractères que l'utilisation d'un nombre comme clé d'objet (conversion en chaîne).const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
Vous pouvez obteniranswer.keys()
les clés etanswer.values()
les valeurs sous forme de tableaux.[...answer]
vous donnera un grand tableau avec toutes les clés / valeurs sous forme de tableaux 2D.Solution ES6 avec réduction (fixe):
la source
Edit 2020 : c'est une assez vieille réponse (neuf ans). L'extension du natif
prototype
générera toujours une discussion . Bien que je pense que le programmeur est libre de choisir son propre style de programmation, voici une approche (plus moderne) du problème sans l'étendreArray.prototype
:L'ancienne (2011) réponse: vous pouvez étendre
Array.prototype
, comme ceci:Afficher l'extrait de code
la source
Ma solution avec ramda:
Lien vers REPL.
la source
Solution utilisant une carte avec une complexité temporelle O (n) .
Démo: http://jsfiddle.net/simevidas/bnACW/
la source
Il existe un moyen bien meilleur et plus simple de le faire en utilisant
ramda.js
. Exemple de code iciconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
la documentation de countBy est à la documentationla source
En utilisant MAP, vous pouvez avoir 2 tableaux dans la sortie: l'un contenant les occurrences et l'autre contenant le nombre d'occurrences.
la source
Consultez le code ci-dessous.
la source
Essaye ça:
la source
Je résolvais un problème similaire sur les guerres de code et j'ai conçu la solution suivante qui a fonctionné pour moi.
Cela donne le nombre le plus élevé d'un entier dans un tableau et également l'entier lui-même. Je pense qu'il peut également être appliqué au tableau de chaînes.
Pour trier correctement les chaînes, retirez le
function(a, b){return a-b}
de l'intérieur de lasort()
portionla source
Voici un moyen de compter les occurrences à l'intérieur d'un tableau d'objets. Il place également le contenu du premier tableau dans un nouveau tableau pour trier les valeurs afin que l'ordre dans le tableau d'origine ne soit pas perturbé. Ensuite, une fonction récursive est utilisée pour parcourir chaque élément et compter la propriété de quantité de chaque objet à l'intérieur du tableau.
la source
la source
la source
Cette question a plus de 8 ans et beaucoup, beaucoup de réponses ne prennent pas vraiment en compte ES6 et ses nombreux avantages.
Il est peut-être encore plus important de réfléchir aux conséquences de notre code pour la collecte des ordures / la gestion de la mémoire chaque fois que nous créons des tableaux supplémentaires, faisons des copies doubles ou triples de tableaux ou même convertissons des tableaux en objets. Ce sont des observations triviales pour les petites applications, mais si l'échelle est un objectif à long terme, réfléchissez-y attentivement.
Si vous avez juste besoin d'un "compteur" pour des types de données spécifiques et que le point de départ est un tableau (je suppose que vous voulez donc une liste ordonnée et profitez des nombreuses propriétés et méthodes proposées par les tableaux), vous pouvez simplement parcourir simplement array1 et remplir array2 avec les valeurs et le nombre d'occurrences de ces valeurs trouvées dans array1.
Aussi simple que cela.
Exemple de classe simple SimpleCounter (ES6) pour la programmation orientée objet et la conception orientée objet
la source
finalList
n'a aucune raison d'être un tableau, et cela n'a aucun avantage par rapport à la faire correctement.Voici une méthode classique de la vieille école pour compter les tableaux.
Vous pouvez d'abord le trier si vous souhaitez un résultat alphabétique, mais si vous souhaitez conserver l'ordre dans lequel les données ont été saisies, essayez-le. Les boucles imbriquées peuvent être un peu plus lentes que certaines des autres méthodes de cette page.
la source