Réponses:
Très simple:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);et les détails de l'implémentation peuvent être discutés à l'intérieur.
[ cette réponse est un peu datée: lisez les modifications ]
Dites bonjour à vos amis: mapet filteret reduceet forEachet everyetc.
(J'écris seulement occasionnellement des boucles for en javascript, car la portée au niveau du bloc est manquante, vous devez donc utiliser une fonction comme corps de la boucle de toute façon si vous avez besoin de capturer ou de cloner votre index ou valeur d'itération. For-loops sont généralement plus efficaces, mais parfois vous avez besoin d'une fermeture.)
Le moyen le plus lisible:
[....].filter(x => x==2).length
(On aurait pu écrire à la .filter(function(x){return x==2}).lengthplace)
Ce qui suit est plus économe en espace (O (1) plutôt que O (N)), mais je ne suis pas sûr du montant des avantages / pénalités que vous pourriez payer en termes de temps (pas plus qu'un facteur constant depuis votre visite chaque élément exactement une fois):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(Si vous avez besoin d'optimiser ce morceau de code particulier, une boucle for peut être plus rapide sur certains navigateurs ... vous pouvez tester des choses sur jsperf.com.)
Vous pouvez alors être élégant et en faire une fonction prototype:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Comme ça:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
Vous pouvez également coller l'ancienne technique classique de la boucle for (voir les autres réponses) dans la définition de propriété ci-dessus (encore une fois, ce serait probablement beaucoup plus rapide).
Édition 2017 :
Oups, cette réponse est devenue plus populaire que la bonne réponse. En fait, utilisez simplement la réponse acceptée. Bien que cette réponse puisse être mignonne, les compilateurs js n'optimisent probablement pas (ou ne peuvent pas en raison des spécifications) de tels cas. Vous devriez donc vraiment écrire une simple boucle for:
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;
}
}
});
Vous pouvez définir une version .countStrictEq(...)qui utilise la ===notion d'égalité. La notion d'égalité peut être importante dans ce que vous faites! (par exemple [1,10,3,'10'].count(10)==2, parce que des nombres comme '4' == 4 en javascript ... donc l'appelant .countEqou .countNonstrictinsiste sur l'utilisation de l' ==opérateur.)
Pensez également à utiliser votre propre structure de données multisets (par exemple, comme celle de python ' collections.Counter') pour éviter d'avoir à faire le comptage en premier lieu.
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 {}
}
}
Démo:
> 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)
note de bas de page: Cependant, si vous vouliez toujours la méthode de programmation fonctionnelle (ou un one-liner jetable sans remplacer Array.prototype), vous pouvez l'écrire plus brièvement de nos jours sous la forme [...].filter(x => x==2).length. Si vous vous souciez des performances, notez que même si ces performances sont asymptotiquement identiques à celles de la boucle for (temps O (N)), cela peut nécessiter une mémoire supplémentaire O (N) (au lieu de mémoire O (1)) car elle sera presque certainement générer un tableau intermédiaire, puis compter les éléments de ce tableau intermédiaire.
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. Ensuite, utilisez-le en appelant count(list)where list est un tableau de nombres. Vous pouvez également const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthcompter les instances de crazyValue dans le tableau d'objets. Notez qu'il s'agit d'une correspondance exacte pour la propriété.
Mise à jour ES6 vers JS:
Notez que vous devez toujours utiliser triple égal: ===pour obtenir une comparaison correcte:
// 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 fonction Arrow unanime suivante (fonction lambda) dans JS:
(x) => {
const k = 2
return k * x
}
peut être simplifiée à cette forme concise pour une seule entrée:
x => 2 * x
où le returnest implicite.
2017: Si quelqu'un est toujours intéressé par la question, ma solution est la suivante:
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 vous utilisez lodash ou un soulignement, la méthode _.countBy fournira un objet de totaux agrégés indexés par chaque valeur du tableau. Vous pouvez le transformer en une seule ligne si vous n'avez besoin de compter qu'une seule valeur:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Cela fonctionne également très bien sur les tableaux de nombres. Le one-liner pour votre exemple serait:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
La façon la plus étrange de faire cela est:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Où:
Ma suggestion, utilisez une boucle while ou for ;-)
Ne pas utiliser de boucle signifie généralement confier le processus à une méthode qui le fait n'utilise une boucle.
Voici une façon dont notre codeur haineux de boucle peut satisfaire sa haine, à un prix:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
Vous pouvez également appeler à plusieurs reprises indexOf, s'il est disponible en tant que méthode de tableau, et déplacer le pointeur de recherche à chaque fois.
Cela ne crée pas de nouveau tableau et la boucle est plus rapide qu'un forEach ou un filtre.
Cela pourrait faire une différence si vous avez un million de membres à regarder.
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- bien que méfiez-vous de cela, sinon votre implémentation ne fonctionnera pas bien avec des chiffres à deux chiffres.
La plupart des solutions publiées utilisant des fonctions de tableau telles que le filtre sont incomplètes car elles ne sont pas paramétrées.
Voici une solution avec laquelle l'élément à compter peut être défini au moment de l'exécution.
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);
L'avantage de cette approche est qu'elle pourrait facilement changer la fonction pour compter par exemple le nombre d'éléments supérieur à X.
Vous pouvez également déclarer la fonction de réduction en ligne
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) ...est plus difficile à lire et ne donne aucun avantage sur juste ... (acc, x) => acc += number == 2.... J'aime votre utilisation de +=au lieu de acc + (number == 2)cependant. Cela ressemble à un HACK de syntaxe injustifié.
Vraiment, pourquoi auriez-vous besoin mapou filterpour cela?
reduceest "né" pour ce genre d'opérations:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
c'est tout! (si item==valdans chaque itération, alors 1 sera ajouté à l'accumulateur count, comme truecela résoudra 1).
En tant que fonction:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Ou, allez-y et étendez vos tableaux:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
Il vaut mieux l'envelopper en fonction:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
Voici un moyen ES2017 + d'obtenir les décomptes de tous les éléments du tableau 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;
});
Vous pouvez également éventuellement trier la sortie:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log (countSorted) pour votre exemple de tableau:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Je crois que vous recherchez une approche fonctionnelle
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' est la condition, remplacez-la par la vôtre.
count = arr.filter(elem => elem === 'a').lengthoucount = arr.filter(elem => {return elem === 'a'}).length
Je suis un fan de la fonction de réduction 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)
En fait, si vous voulez vraiment avoir de la fantaisie, vous pouvez créer une fonction de comptage sur le prototype Array. Ensuite, vous pouvez le réutiliser.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Alors fais
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Solution par récursivité
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, reduceou un moyen simple forLoopet aussi plus coûteux en termes de performances, mais c'est toujours un excellent moyen de le faire avec la récursivité. Mon seul changement est: je pense juste qu'il serait préférable de créer une fonction et d'ajouter un filtre à l'intérieur pour copier le tableau et éviter une mutation du tableau d'origine, puis utiliser le récursif comme fonction interne.
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');
}
Je ferais quelque chose comme ça:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
Créez une nouvelle méthode pour la classe Array dans le fichier de niveau principal et utilisez-la partout dans votre projet.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Utilisez ceci n'importe où dans votre projet -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Voici une seule ligne en javascript.
(v === 2) dans le tableau, en renvoyant un tableau de uns et de zéros.[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
Le résultat est 3.
Selon la façon dont vous souhaitez l'exécuter:
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, …}
Vous pouvez utiliser la propriété length dans le tableau JavaScript:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2