In Javascript versuche ich, ein anfängliches Array von Zahlenwerten zu verwenden und die darin enthaltenen Elemente zu zählen. Im Idealfall wären das Ergebnis zwei neue Arrays, von denen das erste jedes eindeutige Element angibt und das zweite die Häufigkeit enthält, mit der jedes Element auftritt. Ich bin jedoch offen für Vorschläge zum Format der Ausgabe.
Zum Beispiel, wenn das ursprüngliche Array war:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Dann würden zwei neue Arrays erstellt. Das erste würde den Namen jedes einzelnen Elements enthalten:
5, 2, 9, 4
Die zweite würde die Häufigkeit enthalten, mit der dieses Element im ursprünglichen Array vorkam:
3, 5, 1, 1
Da die Zahl 5 im anfänglichen Array dreimal vorkommt, kommt die Zahl 2 fünfmal vor und 9 und 4 erscheinen beide einmal.
Ich habe viel nach einer Lösung gesucht, aber nichts scheint zu funktionieren, und alles, was ich selbst ausprobiert habe, ist lächerlich komplex geworden. Jede Hilfe wäre dankbar!
Vielen Dank :)
quelle
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
dies auf einfache Weise erreichen.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
würde zurückkehren,3
um anzuzeigen, dass das Array '3' fünf enthält.Antworten:
Bitte schön:
Live-Demo: http://jsfiddle.net/simevidas/bnACW/
quelle
O(N log(N))
und derreduce
Antwort . Ich wollte gerade eine solche Antwort einreichen, bevor ich sah, dass sie bereits existierte. Trotzdemcounts[num] = counts[num] ? counts[num]+1 : 1
funktioniert die Antwort auch (entspricht derif(!result[a[i]])result[a[i]]=0
Antwort, die eleganter, aber weniger leicht zu lesen ist); Diese Antworten können geändert werden, um eine "schönere" Version der for-Schleife zu verwenden, möglicherweise eine for-Schleife eines Drittanbieters, aber ich habe das irgendwie ignoriert, da die standardmäßigen indexbasierten for-Schleifen leider die Standardeinstellung sind.Sie können ein Objekt verwenden, um die Ergebnisse zu speichern:
Jetzt kann Ihr Zählobjekt Ihnen sagen, wie hoch die Zählung für eine bestimmte Zahl ist:
Wenn Sie eine Reihe von Mitgliedern erhalten möchten, verwenden Sie einfach die
keys()
Funktionenquelle
Object.keys()
Funktion nur in IE9 +, FF4 +, SF5 +, CH6 + unterstützt wird, Opera jedoch nicht. Ich denke, der größte Show-Stopper hier ist IE9 + .counts[num] = (counts[num] || 0) + 1
. Auf diese Weise müssen Sie dort nurcounts[num]
zweimal statt dreimal in diese eine Zeile schreiben .[5, "5"]
Ich werde einfach sagen, dass du"5"
zwei Mal hast . Oder das Zählen von Instanzen verschiedener Objekte sagt Ihnen nur, dass es viele gibt[object Object]
. Usw. usw.quelle
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Wenn Sie Unterstrich oder Lodash verwenden, ist dies am einfachsten:
So dass:
Wie von anderen hervorgehoben, können Sie dann die Funktionen
_.keys()
und_.values()
für das Ergebnis ausführen , um nur die eindeutigen Zahlen und deren Vorkommen zu erhalten. Aber meiner Erfahrung nach ist das ursprüngliche Objekt viel einfacher zu handhaben.quelle
Verwenden Sie keine zwei Arrays für das Ergebnis, sondern ein Objekt:
Dann
result
sieht es so aus:quelle
Wie wäre es mit einer ECMAScript2015-Option.
In diesem Beispiel wird das Eingabearray an den
Set
Konstruktor übergeben, wodurch eine Sammlung eindeutiger Werte erstellt wird. Die Spread-Syntax erweitert diese Werte dann zu einem neuen Array, sodass wir dies aufrufenmap
und in ein zweidimensionales Array von[value, count]
Paaren übersetzen können - dh die folgende Struktur:Das neue Array wird dann an den
Map
Konstruktor übergeben, was zu einem iterierbaren Objekt führt:Das Tolle an einem
Map
Objekt ist, dass es Datentypen beibehält - das heißt, esaCount.get(5)
wird zurückkehren,3
aberaCount.get("5")
zurückkehrenundefined
. Außerdem kann jeder Wert / Typ als Schlüssel fungieren, was bedeutet, dass diese Lösung auch mit einer Reihe von Objekten funktioniert.Code-Snippet anzeigen
quelle
Set
verwendet Objektreferenzen zur Eindeutigkeit und bietet keine API zum Vergleich von "ähnlichen" Objekten. Wenn Sie diesen Ansatz für eine solche Aufgabe verwenden möchten, benötigen Sie eine Zwischenreduktionsfunktion, die eine Reihe eindeutiger Instanzen garantiert. Es ist nicht das effizienteste, aber ich habe hier ein kurzes Beispiel zusammengestellt .Ich denke, dies ist der einfachste Weg, um Vorkommen mit demselben Wert im Array zu zählen.
quelle
a.filter(value => !value).length
mit der neuen js-SyntaxEinzeilige ES6-Lösung. So viele Antworten mit Objekt als Karte, aber ich kann niemanden sehen, der eine tatsächliche Karte verwendet
Verwenden
map.keys()
diese , um eindeutige Elemente zu erhaltenVerwenden
map.values()
diese , um die Vorkommen abzurufenVerwenden Sie
map.entries()
, um die Paare [Element, Frequenz] zu erhalten.quelle
quelle
Wenn Sie einen einzelnen Liner bevorzugen.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Bearbeiten (6/12/2015) : Die Erklärung von innen nach außen. countMap ist eine Karte, die ein Wort mit seiner Häufigkeit abbildet, wobei wir die anonyme Funktion sehen können. Reduzieren wendet die Funktion mit Argumenten an, da alle Array-Elemente und countMap als Rückgabewert des letzten Funktionsaufrufs übergeben werden. Der letzte Parameter ({}) ist der Standardwert von countMap für den ersten Funktionsaufruf.
quelle
;
,{
und}
. ... OK. Ich denke, mit dieser Definition eines Einzeilers können wir Conways Spiel des Lebens als "Oneliner" schreiben.Die ES6-Version sollte viel einfacher sein (eine weitere einzeilige Lösung).
Eine Karte anstelle eines einfachen Objekts hilft uns, verschiedene Arten von Elementen zu unterscheiden, oder alle Zählungen basieren auf Zeichenfolgen
quelle
Wenn Sie einen Unterstrich verwenden, können Sie den funktionalen Weg gehen
Ihr erstes Array ist also
und das zweite Array ist
Das meiste davon verwendet standardmäßig native Javascript-Funktionen, sofern diese verfügbar sind
Demo: http://jsfiddle.net/dAaUU/
quelle
Basierend auf der Antwort von @adamse und @pmandell (die ich positiv bewertet habe) können Sie dies in ES6 in einer Zeile tun :
||
, um die Codegröße zu reduzieren und sie lesbarer zu machen.Es kann verwendet werden, um Zeichen zu zählen :
quelle
|| 0
:(r,k)=>{r[k]=(r[k]||0)+1;return r}
Hier ist nur etwas Leichtes und Leichtes für die Augen ...
Edit: Und da willst du alle Vorkommen ...
quelle
So würde ich es mit einigen der neuesten Javascript-Funktionen machen:
Reduzieren Sie zunächst das Array auf einen
Map
der folgenden Werte:Wenn Sie a verwenden
Map
, kann Ihr Startarray einen beliebigen Objekttyp enthalten, und die Anzahl ist korrekt. Ohne aMap
geben Ihnen einige Objekttypen seltsame Zählungen. Weitere Informationen zu den Unterschieden finden Sie in denMap
Dokumenten .Dies kann auch mit einem Objekt erfolgen, wenn alle Ihre Werte Symbole, Zahlen oder Zeichenfolgen sind:
Oder auf funktionale Weise ohne Mutation etwas schicker, unter Verwendung von Destrukturierungs- und Objektverbreitungssyntax:
Zu diesem Zeitpunkt können Sie das
Map
Objekt oder für Ihre Zählungen verwenden (und die Karte ist im Gegensatz zu einem Objekt direkt iterierbar) oder in zwei Arrays konvertieren.Für die
Map
:Oder für das Objekt:
quelle
quelle
Map
stattdessen auch auf a reduzieren , da dadurch die Typumwandlung vermieden wird, die durch die Verwendung einer Zahl als Objektschlüssel (Casting als Zeichenfolge) erfolgt.const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
Sie könnenanswer.keys()
für die Schlüssel undanswer.values()
für die Werte als Arrays erhalten.[...answer]
Sie erhalten ein großes Array mit allen Schlüsseln / Werten als 2D-Arrays.ES6-Lösung mit Reduktion (fest):
quelle
Edit 2020 : Dies ist eine ziemlich alte Antwort (neun Jahre). Das Erweitern des Native
prototype
führt immer zu Diskussionen . Obwohl ich denke, dass die Programmiererin frei ist, ihren eigenen Programmierstil zu wählen, ist hier ein (modernerer) Ansatz für das Problem, ohne es zu erweiternArray.prototype
:Die alte (2011) Antwort: Sie könnten so erweitern
Array.prototype
:Code-Snippet anzeigen
quelle
Meine Lösung mit Ramda:
Link zu REPL.
quelle
Lösung unter Verwendung einer Karte mit O (n) Zeitkomplexität.
Demo: http://jsfiddle.net/simevidas/bnACW/
quelle
Es gibt eine viel bessere und einfachere Möglichkeit, dies zu tun
ramda.js
. Codebeispiel hierconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
Die countBy-Dokumentation befindet sich in der Dokumentationquelle
Mit MAP können Sie zwei Arrays in der Ausgabe haben: Eines enthält die Vorkommen und das andere enthält die Anzahl der Vorkommen.
quelle
Überprüfen Sie den Code unten.
quelle
Versuche dies:
quelle
Ich habe ein ähnliches Problem mit Codewars gelöst und die folgende Lösung entwickelt, die für mich funktioniert hat.
Dies gibt die höchste Anzahl einer Ganzzahl in einem Array und auch die Ganzzahl selbst an. Ich denke, es kann auch auf String-Arrays angewendet werden.
Um die Saiten richtig zu sortieren, entfernen Sie die
function(a, b){return a-b}
aus dem Inneren dessort()
Teilsquelle
Hier ist eine Möglichkeit, Vorkommen in einem Array von Objekten zu zählen. Außerdem wird der Inhalt des ersten Arrays in einem neuen Array platziert, um die Werte so zu sortieren, dass die Reihenfolge im ursprünglichen Array nicht unterbrochen wird. Dann wird eine rekursive Funktion verwendet, um jedes Element zu durchlaufen und die Mengeneigenschaft jedes Objekts innerhalb des Arrays zu zählen.
quelle
quelle
quelle
Diese Frage ist mehr als 8 Jahre alt und viele, viele Antworten berücksichtigen ES6 und seine zahlreichen Vorteile nicht wirklich .
Vielleicht ist es noch wichtiger, über die Konsequenzen unseres Codes für die Speicherbereinigung / Speicherverwaltung nachzudenken, wenn wir zusätzliche Arrays erstellen, doppelte oder dreifache Kopien von Arrays erstellen oder sogar Arrays in Objekte konvertieren. Dies sind triviale Beobachtungen für kleine Anwendungen, aber wenn Skalierung ein langfristiges Ziel ist, denken Sie gründlich darüber nach.
Wenn Sie nur einen "Zähler" für bestimmte Datentypen benötigen und der Ausgangspunkt ein Array ist (ich nehme an, Sie möchten daher eine geordnete Liste und die vielen Eigenschaften und Methoden nutzen, die Arrays bieten), können Sie einfach Array1 durchlaufen und füllen Array2 mit den Werten und der Anzahl der Vorkommen für diese Werte in Array1.
So einfach ist das.
Beispiel einer einfachen Klasse SimpleCounter (ES6) für objektorientierte Programmierung und objektorientiertes Design
quelle
finalList
ist sie nicht objektorientiert, hat keinen Grund, ein Array zu sein, und dies hat keine Vorteile gegenüber einer ordnungsgemäßen Ausführung.Hier ist eine klassische Old-School-Methode zum Zählen von Arrays.
Sie können es zuerst sortieren, wenn Sie ein alphabetisches Ergebnis wünschen. Wenn Sie jedoch die Reihenfolge beibehalten möchten, in der die Daten eingegeben wurden, versuchen Sie es. Verschachtelte Schleifen sind möglicherweise etwas langsamer als einige der anderen Methoden auf dieser Seite.
quelle