Ich habe ein Array:
[1, 2, 3, 5, 2, 8, 9, 2]
Ich würde gerne wissen, wie viele 2
s im Array sind.
Was ist die eleganteste Art, dies in JavaScript zu tun, ohne eine Schleife mit einer for
Schleife zu erstellen?
javascript
Leem
quelle
quelle
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:
map
undfilter
undreduce
undforEach
undevery
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:
(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):
(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:
So was:
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:
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.countEq
oder.countNonstrict
betont, 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.Demo:
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.quelle
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 auchconst count = (list) => list.filter((x) => x.someProp === 'crazyValue').length
Instanzen 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:Die folgende einstimmige Pfeilfunktion (Lambda-Funktion) in JS:
kann zu dieser prägnanten Form für eine einzelne Eingabe vereinfacht werden:
wo das
return
impliziert ist.quelle
2017: Wenn sich noch jemand für die Frage interessiert, lautet meine Lösung wie folgt:
quelle
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:
Dies funktioniert auch gut bei Arrays von Zahlen. Der Einzeiler für Ihr Beispiel wäre:
quelle
Der seltsamste Weg, den ich mir vorstellen kann, ist:
Wo:
Mein Vorschlag, benutze eine Weile oder eine Schleife ;-)
quelle
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:
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.
quelle
String(a).match(/2/g).length + 1
dies 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.
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
quelle
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+=
anstattacc + (number == 2)
obwohl. Fühlt sich allerdings wie ein ungerechtfertigter Syntax-HACK an.Wirklich, warum brauchst du
map
oderfilter
dafür?reduce
wurde 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==val
in jeder Iteration, wird 1 zum Akkumulator hinzugefügtcount
, wie in aufgelösttrue
wird1
).Als eine Funktion:
Oder erweitern Sie Ihre Arrays:
quelle
Es ist besser, es in Funktion zu verpacken:
quelle
Hier ist eine ES2017 + -Methode, um die Anzahl aller Array-Elemente in O (N) abzurufen:
Optional können Sie die Ausgabe auch sortieren:
console.log (countSorted) für Ihr Beispielarray:
quelle
Ich glaube, was Sie suchen, ist ein funktionaler Ansatz
elem === 'a' ist die Bedingung, ersetzen Sie es durch Ihre eigene.
quelle
count = arr.filter(elem => elem === 'a').length
odercount = arr.filter(elem => {return elem === 'a'}).length
Ich bin ein Anfänger der Reduzierungsfunktion von js array.
Wenn Sie wirklich Lust haben, können Sie eine Zählfunktion für den Array-Prototyp erstellen. Dann können Sie es wiederverwenden.
Dann mach
quelle
Lösung durch Rekursion
quelle
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.reduce
forLoop
Ich würde so etwas tun:
quelle
Erstellen Sie eine neue Methode für die Array-Klasse in einer Datei auf Kernebene und verwenden Sie sie im gesamten Projekt.
Verwenden Sie dies überall in Ihrem Projekt -
quelle
Hier ist ein Einzeiler in Javascript.
(v === 2)
im Array und geben Sie ein Array mit Einsen und Nullen zurück.Das Ergebnis ist
3
.quelle
Abhängig davon, wie Sie es ausführen möchten:
quelle
Sie können die Eigenschaft length im JavaScript-Array verwenden:
quelle