Antworten:
Sehr einfach:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);und die Implementierungsdetails können im Inneren argumentiert werden.
[ Diese Antwort ist etwas veraltet: Lesen Sie die Änderungen ]
Sag Hallo zu deinen Freunden: mapund filterund reduceund forEachundevery usw.
(Ich schreibe nur gelegentlich for-Schleifen in Javascript, da das Scoping auf Blockebene fehlt. Sie müssen daher ohnehin eine Funktion als Hauptteil der Schleife verwenden, wenn Sie Ihren Iterationsindex oder -wert erfassen oder klonen müssen. For-Schleifen sind im Allgemeinen effizienter, aber manchmal brauchen Sie einen Verschluss.)
Der am besten lesbare Weg:
[....].filter(x => x==2).length
(Wir hätten schreiben können .filter(function(x){return x==2}).length stattdessen )
Das Folgende ist platzsparender (O (1) als O (N)), aber ich bin mir nicht sicher, wie viel Zeit / Strafe Sie in Bezug auf die Zeit zahlen könnten (nicht mehr als ein konstanter Faktor seit Ihrem Besuch jedes Element genau einmal):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(Wenn Sie diesen bestimmten Code optimieren müssen, ist eine for-Schleife in einigen Browsern möglicherweise schneller. Sie können die Dinge auf jsperf.com testen.)
Sie können dann elegant sein und daraus einen Prototyp machen:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
So was:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
Sie können auch die reguläre alte For-Loop-Technik (siehe andere Antworten) in die obige Eigenschaftsdefinition einfügen (auch dies wäre wahrscheinlich viel schneller).
2017 bearbeiten :
Hoppla, diese Antwort ist populärer geworden als die richtige. Verwenden Sie einfach die akzeptierte Antwort. Während diese Antwort niedlich sein mag, optimieren die js-Compiler solche Fälle wahrscheinlich nicht (oder können es aufgrund der Spezifikation nicht). Sie sollten also wirklich eine einfache for-Schleife schreiben:
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;
}
}
});
Sie könnten eine Version definieren, .countStrictEq(...)die den ===Begriff der Gleichheit verwendet. Der Begriff der Gleichheit kann für das, was Sie tun, wichtig sein! (Zum Beispiel [1,10,3,'10'].count(10)==2, weil Zahlen wie '4' == 4 in Javascript ... daher wird es genannt .countEqoder .countNonstrictbetont, dass es das verwendet== Operator .)
Erwägen Sie auch die Verwendung Ihrer eigenen Multiset-Datenstruktur (z. B. Python ' collections.Counter'), um zu vermeiden, dass Sie zuerst zählen müssen.
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 {}
}
}
Demo:
> 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)
Nebenbemerkung: Wenn Sie jedoch immer noch die Möglichkeit der funktionalen Programmierung (oder einen wegwerfbaren Einzeiler ohne Überschreiben von Array.prototype) wollten, könnten Sie ihn heutzutage knapper schreiben als [...].filter(x => x==2).length. Wenn Sie sich für die Leistung interessieren, beachten Sie, dass dies zwar asymptotisch die gleiche Leistung wie die for-Schleife (O (N) -Zeit) ist, jedoch möglicherweise O (N) zusätzlichen Speicher (anstelle von O (1) -Speicher) benötigt, da dies fast der Fall ist Erzeugen Sie auf jeden Fall ein Zwischenarray und zählen Sie dann die Elemente dieses Zwischenarrays.
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. Verwenden Sie es dann, indem Sie aufrufen, count(list)wobei list ein Array von Zahlen ist. Sie können auch const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthInstanzen von crazyValue im Array von Objekten zählen. Beachten Sie, dass es eine genaue Übereinstimmung für die Eigenschaft ist.
ES6-Update auf JS:
Beachten Sie, dass Sie immer Triple Equals verwenden sollten: ===um einen korrekten Vergleich zu erhalten:
// 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
Die folgende einstimmige Pfeilfunktion (Lambda-Funktion) in JS:
(x) => {
const k = 2
return k * x
}
kann zu dieser prägnanten Form für eine einzelne Eingabe vereinfacht werden:
x => 2 * x
wo das returnimpliziert ist.
2017: Wenn sich noch jemand für die Frage interessiert, lautet meine Lösung wie folgt:
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);
Wenn Sie lodash verwenden oder einen Unterstrich verwenden, stellt die Methode _.countBy ein Objekt mit Gesamtsummen bereit, die von jedem Wert im Array eingegeben werden. Sie können dies in einen Einzeiler verwandeln, wenn Sie nur einen Wert zählen müssen:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Dies funktioniert auch gut bei Arrays von Zahlen. Der Einzeiler für Ihr Beispiel wäre:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Der seltsamste Weg, den ich mir vorstellen kann, ist:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Wo:
Mein Vorschlag, benutze eine Weile oder eine Schleife ;-)
Wenn Sie keine Schleife verwenden, müssen Sie den Prozess normalerweise an eine Methode übergeben, die dies tut eine Schleife verwendet.
Hier ist eine Möglichkeit, wie unser Loop-Hass-Codierer seinen Ekel zu einem Preis befriedigen kann:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
Sie können indexOf auch wiederholt aufrufen, wenn es als Array-Methode verfügbar ist, und den Suchzeiger jedes Mal verschieben.
Dadurch wird kein neues Array erstellt, und die Schleife ist schneller als ein forEach oder Filter.
Es könnte einen Unterschied machen, wenn Sie eine Million Mitglieder zum Anschauen haben.
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 + 1dies oder Ihre Implementierung nicht mit zweistelligen Zahlen gut funktioniert.
Die meisten veröffentlichten Lösungen, die Array-Funktionen wie Filter verwenden, sind unvollständig, da sie nicht parametrisiert sind.
Hier ist eine Lösung, mit der das zu zählende Element zur Laufzeit eingestellt werden kann.
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);
Der Vorteil dieses Ansatzes besteht darin, dass die Funktion leicht geändert werden kann, um beispielsweise die Anzahl der Elemente größer als X zu zählen.
Sie können die Reduktionsfunktion auch inline deklarieren
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) ...ist schwerer zu lesen und bietet keinen Vorteil gegenüber nur ... (acc, x) => acc += number == 2.... Ich mag deine Verwendung von +=anstatt acc + (number == 2)obwohl. Fühlt sich allerdings wie ein ungerechtfertigter Syntax-HACK an.
Wirklich, warum brauchst du mapoder filterdafür?
reducewurde für diese Art von Operationen "geboren":
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
das ist es! (Wenn item==valin jeder Iteration, wird 1 zum Akkumulator hinzugefügt count, wie in aufgelöst truewird 1).
Als eine Funktion:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Oder erweitern Sie Ihre Arrays:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
Es ist besser, es in Funktion zu verpacken:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
Hier ist eine ES2017 + -Methode, um die Anzahl aller Array-Elemente in O (N) abzurufen:
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] += 1) : 1;
});
Optional können Sie die Ausgabe auch sortieren:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log (countSorted) für Ihr Beispielarray:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Ich glaube, was Sie suchen, ist ein funktionaler Ansatz
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' ist die Bedingung, ersetzen Sie es durch Ihre eigene.
count = arr.filter(elem => elem === 'a').lengthodercount = arr.filter(elem => {return elem === 'a'}).length
Ich bin ein Anfänger der Reduzierungsfunktion von js array.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
Wenn Sie wirklich Lust haben, können Sie eine Zählfunktion für den Array-Prototyp erstellen. Dann können Sie es wiederverwenden.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Dann mach
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Lösung durch Rekursion
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, wenn es um die Leistung geht, aber dennoch eine großartige Möglichkeit, dies mit Rekursion zu tun. Meine einzige Änderung ist: Ich denke, es wäre besser, eine Funktion zu erstellen und einen Filter hinzuzufügen, um das Array zu kopieren und eine Mutation des ursprünglichen Arrays zu vermeiden. Verwenden Sie dann die rekursive Funktion als innere Funktion. reduceforLoop
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');
}
Ich würde so etwas tun:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
Erstellen Sie eine neue Methode für die Array-Klasse in einer Datei auf Kernebene und verwenden Sie sie im gesamten Projekt.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Verwenden Sie dies überall in Ihrem Projekt -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Hier ist ein Einzeiler in Javascript.
(v === 2) im Array und geben Sie ein Array mit Einsen und Nullen zurück.[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
Das Ergebnis ist 3.
Abhängig davon, wie Sie es ausführen möchten:
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, …}
Sie können die Eigenschaft length im JavaScript-Array verwenden:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2