W JavaScript próbuję pobrać początkową tablicę wartości liczbowych i policzyć w niej elementy. Idealnie, wynikiem byłyby dwie nowe tablice, pierwsza określająca każdy unikalny element, a druga zawierająca liczbę wystąpień każdego elementu. Jestem jednak otwarty na sugestie dotyczące formatu danych wyjściowych.
Na przykład, jeśli początkowa tablica to:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Następnie powstałyby dwie nowe tablice. Pierwszy zawierałby nazwę każdego unikalnego elementu:
5, 2, 9, 4
Drugi zawierałby liczbę wystąpień tego elementu w początkowej tablicy:
3, 5, 1, 1
Ponieważ liczba 5 występuje trzy razy w początkowej tablicy, liczba 2 występuje pięć razy, a 9 i 4 pojawiają się raz.
Dużo szukałem rozwiązania, ale wydaje się, że nic nie działa, a wszystko, co sam próbowałem, okazało się absurdalnie skomplikowane. Każda pomoc będzie mile widziana!
Dzięki :)
źródło
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
w prosty sposób.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
powróciłby,3
aby wskazać, że w tablicy znajdują się piątki „3”.Odpowiedzi:
Proszę bardzo:
Demo na żywo: http://jsfiddle.net/simevidas/bnACW/
źródło
O(N log(N))
a przyrost elegancji nie jest tego wartreduce
odpowiedź. Już miałem przesłać taką odpowiedź, zanim zobaczyłem, że już istnieje. Niemniej jednakcounts[num] = counts[num] ? counts[num]+1 : 1
odpowiedź również działa (odpowiednikif(!result[a[i]])result[a[i]]=0
odpowiedzi, która jest bardziej elegancka, ale trudniejsza do odczytania); odpowiedzi te można zmodyfikować, aby użyć „ładniejszej” wersji pętli for, być może trzeciej pętli for, ale zignorowałem to, ponieważ standardowe pętle for oparte na indeksie są niestety domyślne.Możesz użyć obiektu do przechowywania wyników:
Więc teraz twój obiekt counts może ci powiedzieć, co to jest liczba dla określonej liczby:
Jeśli chcesz uzyskać tablicę członków, po prostu użyj
keys()
funkcjiźródło
Object.keys()
funkcja jest obsługiwana tylko w IE9 +, FF4 +, SF5 +, CH6 +, ale Opera jej nie obsługuje. Myślę, że największym ogranicznikiem programu jest IE9 + .counts[num] = (counts[num] || 0) + 1
. W ten sposób musisz napisać tylkocounts[num]
dwa razy zamiast trzech razy w tej jednej linii.[5, "5"]
powie po prostu, że masz"5"
dwa razy. Lub zliczanie instancji różnych przedmiotów po prostu powie ci, że jest ich dużo[object Object]
. Itd. Itp.źródło
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Jeśli używasz podkreślenia lub lodash, jest to najprostsza rzecz do zrobienia:
Tak, że:
Jak zauważyli inni, możesz następnie wykonać funkcje
_.keys()
i_.values()
na wyniku, aby uzyskać tylko unikalne liczby i ich wystąpienia. Jednak z mojego doświadczenia wynika, że łatwiej jest sobie poradzić z oryginalnym przedmiotem.źródło
Nie używaj dwóch tablic dla wyniku, użyj obiektu:
Następnie
result
będzie wyglądać następująco:źródło
Co powiesz na opcję ECMAScript2015.
Ten przykład przekazuje tablicę wejściową do
Set
konstruktora, tworząc kolekcję unikalnych wartości. Składnia spread następnie rozszerza te wartości do nowej tablicy, dzięki czemu możemy zadzwonićmap
i przełożyć to na dwuwymiarowej tablicy[value, count]
parach - czyli o następującej strukturze:Nowa tablica jest następnie przekazywana do
Map
konstruktora, w wyniku czego powstaje iterowalny obiekt:Wspaniałą rzeczą w
Map
obiekcie jest to, że zachowuje typy danych - to znaczy,aCount.get(5)
że zwróci,3
aleaCount.get("5")
zwróciundefined
. Pozwala również, aby dowolna wartość / typ działała jako klucz, co oznacza, że to rozwiązanie będzie również działać z tablicą obiektów.Pokaż fragment kodu
źródło
Set
używa odwołań do obiektów dla unikalności i nie oferuje interfejsu API do porównywania „podobnych” obiektów. Jeśli chcesz zastosować to podejście do takiego zadania, potrzebujesz pośredniej funkcji redukcji, która gwarantuje szereg unikalnych instancji. Nie jest to najbardziej wydajny, ale podam tutaj szybki przykład .Myślę, że to najprostszy sposób liczenia wystąpień o tej samej wartości w tablicy.
źródło
a.filter(value => !value).length
z nową składnią jsJednoelementowe rozwiązanie ES6. Tak wiele odpowiedzi przy użyciu obiektu jako mapy, ale nie widzę nikogo używającego prawdziwej mapy
Użyj,
map.keys()
aby uzyskać unikalne elementyUżyj,
map.values()
aby uzyskać wystąpieniaUżyj,
map.entries()
aby uzyskać pary [element, częstotliwość]źródło
źródło
Jeśli wolisz pojedynczą wkładkę.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Edytuj (6/12/2015) : Wyjaśnienie od wewnątrz. countMap to mapa, która odwzorowuje słowo z częstotliwością, którą możemy zobaczyć anonimową funkcję. Zmniejsza to zastosowanie funkcji z argumentami, ponieważ wszystkie elementy tablicy i countMap są przekazywane jako wartość zwracana ostatniego wywołania funkcji. Ostatni parametr ({}) jest domyślną wartością countMap dla pierwszego wywołania funkcji.
źródło
;
,{
i}
. ... DOBRZE. Myślę, że z tą definicją jednego linijki możemy napisać Conway's Game of Life jako „oneliner”.Wersja ES6 powinna znacznie uprościć (kolejne rozwiązanie jednoliniowe)
Mapa zamiast zwykłego obiektu, który pomaga nam rozróżniać różne typy elementów, w przeciwnym razie wszystkie liczenia są oparte na ciągach znaków
źródło
Jeśli używasz podkreślenia, możesz wybrać trasę funkcjonalną
więc twoja pierwsza tablica to
a druga tablica to
większość z nich będzie domyślnie natywnych funkcji javascript, jeśli są one dostępne
demo: http://jsfiddle.net/dAaUU/
źródło
Na podstawie odpowiedzi z @adamse i @pmandell (co upvote), w ES6 można zrobić to w jednym wierszu :
||
aby zmniejszyć rozmiar kodu i uczynić go bardziej czytelnym.Może być używany do liczenia znaków :
źródło
|| 0
:(r,k)=>{r[k]=(r[k]||0)+1;return r}
Oto coś lekkiego i łatwego dla oczu ...
Edycja: A ponieważ chcesz wszystkie wystąpienia ...
źródło
Oto jak bym to zrobił z niektórymi najnowszymi funkcjami javascript:
Najpierw zmniejsz tablicę do jednego
Map
z poniższych:Korzystając z a
Map
, tablica początkowa może zawierać dowolny typ obiektu, a liczby będą prawidłowe. Bez aMap
niektóre typy obiektów dają dziwne liczby. ZobaczMap
dokumentację, aby uzyskać więcej informacji na temat różnic.Można to również zrobić z obiektem, jeśli wszystkie wartości to symbole, liczby lub ciągi znaków:
Lub nieco bardziej funkcjonalny w sposób funkcjonalny, bez mutacji, przy użyciu destrukcji i składni rozproszenia obiektów:
W tym momencie możesz użyć
Map
obiektu lub do swoich obliczeń (a mapa jest iterowalna bezpośrednio, w przeciwieństwie do obiektu), lub przekonwertować ją na dwie tablice.Dla
Map
:Lub dla obiektu:
źródło
źródło
Map
zamiast tego zredukować do , ponieważ pozwoli to uniknąć rzutowania typowego, jak przy użyciu liczby jako klucza obiektowego (rzutowanie jako ciąg znaków).const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
Możesz uzyskaćanswer.keys()
klucze, aanswer.values()
wartości jako tablice.[...answer]
da ci dużą tablicę ze wszystkimi kluczami / wartościami jak tablice 2d.Rozwiązanie ES6 z redukcją (naprawione):
źródło
Edycja 2020 : to dość stara odpowiedź (dziewięć lat). Rozszerzenie natywnego
prototype
zawsze będzie generowało dyskusję . Chociaż myślę, że programista może wybrać własny styl programowania, oto (bardziej nowoczesne) podejście do problemu bez rozszerzaniaArray.prototype
:Stara (2011) odpowiedź: możesz rozszerzyć
Array.prototype
, tak jak to:Pokaż fragment kodu
źródło
Moje rozwiązanie z ramda:
Link do REPL.
źródło
Rozwiązanie za pomocą mapy o złożoności czasowej O (n) .
Demo: http://jsfiddle.net/simevidas/bnACW/
źródło
Jest o wiele lepszy i łatwy sposób, w jaki możemy to zrobić za pomocą
ramda.js
. Przykładowy kod tutajconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
Dokumentacja countBy znajduje się w dokumentacjiźródło
Korzystając z MAP , możesz mieć 2 tablice wyjściowe: jedna zawierająca wystąpienia, a druga zawiera liczbę wystąpień.
źródło
Sprawdź kod poniżej.
źródło
Spróbuj tego:
źródło
Rozwiązałem podobny problem w programistach i opracowałem następujące rozwiązanie, które działało dla mnie.
Daje to najwyższą liczbę całkowitą w tablicy, a także samą liczbę całkowitą. Myślę, że można go również zastosować do tablicy ciągów.
Aby prawidłowo posortować ciągi, usuń je
function(a, b){return a-b}
zsort()
częściźródło
Oto sposób na policzenie wystąpień wewnątrz tablicy obiektów. Umieszcza również zawartość pierwszej tablicy w nowej tablicy, aby posortować wartości, aby kolejność w oryginalnej tablicy nie została zakłócona. Następnie używana jest funkcja rekurencyjna, aby przejść przez każdy element i policzyć właściwość ilości każdego obiektu w tablicy.
źródło
źródło
źródło
To pytanie ma ponad 8 lat i wiele, wiele odpowiedzi tak naprawdę nie uwzględnia ES6 i jego licznych zalet.
Być może jeszcze ważniejsze jest zastanowienie się nad konsekwencjami naszego kodu dla odśmiecania pamięci / zarządzania pamięcią, ilekroć tworzymy dodatkowe tablice, tworzymy podwójne lub potrójne kopie tablic, a nawet przekształcamy tablice w obiekty. Są to trywialne obserwacje dla małych zastosowań, ale jeśli skala jest celem długoterminowym, zastanów się nad nimi dokładnie.
Jeśli potrzebujesz tylko „licznika” dla określonych typów danych, a punktem początkowym jest tablica (zakładam, że chcesz mieć uporządkowaną listę i skorzystać z wielu właściwości tablic właściwości i metod), możesz po prostu iterować przez tablicę 1 i wypełnić tablica2 z wartościami i liczbą wystąpień tych wartości znalezionych w tablicy1.
Tak proste jak to.
Przykład prostej klasy SimpleCounter (ES6) do programowania obiektowego i projektowania obiektowego
źródło
finalList
nie ma powodu, aby być tablicą, a to nie ma przewagi nad prawidłowym wykonaniem.Oto klasyczna oldschoolowa metoda liczenia tablic.
Możesz go najpierw posortować, jeśli chcesz uzyskać wynik alfabetyczny, ale jeśli chcesz zachować kolejność wprowadzania danych, spróbuj. Zagnieżdżone pętle mogą być nieco wolniejsze niż niektóre inne metody na tej stronie.
źródło