Czy istnieje javascript równoważny z funkcją zip Pythona? Oznacza to, że biorąc pod uwagę wiele tablic o równej długości, należy utworzyć tablicę par.
Na przykład, jeśli mam trzy tablice, które wyglądają tak:
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
Tablica wyjściowa powinna być:
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
forEach
,reduce
,map
,every
, itd. To było po prostu zdarza się, żezip
nie „dokonać cięcia” (aflatMap
także jej brak), nie ze względów wydajności - ale szczerze mówiąc, .NET (3.5) nie miał Zip'a na Enumerable od kilku lat! Każda biblioteka „funkcjonalna”, taka jak podkreślenie / lodash (lodash 3.x ma ocenę leniwej sekwencji), zapewni równoważną funkcję zip.Odpowiedzi:
Aktualizacja 2016:
Oto wersja Ecnacript 6 Snazziera:
Ilustracja ekwiwal. do Pythona {
zip(*args)
}:(a FizzyTea wskazuje, że ES6 ma składnię argumentów variadic, więc poniższa definicja funkcji będzie działać jak python, ale zobacz poniżej zrzeczenie się odpowiedzialności ... nie będzie to jej własna odwrotność, więc
zip(zip(x))
nie będzie równax
; chociaż, jak zauważa Matt Kramerzip(...zip(...x))==x
(jak w zwykłym pythoniezip(*zip(*x))==x
))Alternatywna definicja ekwiwal. do Pythona {
zip
}:(Należy pamiętać, że
...
składni mogą występować problemy z wydajnością w tym czasie i być może w przyszłości, więc jeśli użyjesz drugiej odpowiedzi z argumentami variadic, możesz ją dokładnie przetestować).Oto oneliner:
Powyższe zakłada, że tablice są równej wielkości, tak jak powinny. Zakłada się także, że przekazujesz argument z jednej listy list, w przeciwieństwie do wersji Pythona, w której lista argumentów jest variadic.Jeśli chcesz wszystkie te „funkcje”, patrz poniżej. Zajmuje to około 2 dodatkowe linie kodu.
Poniższe będzie naśladować
zip
zachowanie Pythona w przypadkach krawędziowych, w których tablice nie są równej wielkości, w milczeniu udając, że dłuższe części tablic nie istnieją:To naśladuje
itertools.zip_longest
zachowanie Pythona , wstawiającundefined
tam , gdzie tablice nie są zdefiniowane:Jeśli użyjesz tych dwóch ostatnich wersji (variadic aka. Wersje z wieloma argumentami), zip nie będzie już własną odwrotnością. Aby naśladować
zip(*[...])
idiom z Pythona, musisz to zrobić,zip.apply(this, [...])
gdy chcesz odwrócić funkcję zip lub jeśli podobnie chcesz mieć zmienną liczbę list jako dane wejściowe.uzupełnienie :
Aby uczynić ten uchwyt dowolną iterowalną (np. W Pythonie możesz używać
zip
na ciągach, zakresach, obiektach mapy itp.), Możesz zdefiniować:Jeśli jednak napiszesz
zip
w następujący sposób , nawet to nie będzie konieczne:Próbny:
(Lub możesz użyć
range(...)
funkcji w stylu Pythona, jeśli już ją napisałeś. W końcu będziesz mógł używać wyrażeń tablicowych ECMAScript lub generatorów.)źródło
zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]));
zip(zip(x)) = x
, nadal możesz się w tym cieszyćzip(...zip(...x)) = x
.const the_longest_array_length = Math.max(...(arrays.map(array => array.length)));
Sprawdź bibliotekę Underscore .
- Powiedz ludziom, którzy to zrobili
Niedawno zacząłem używać go specjalnie do tej
zip()
funkcji i pozostawiło to pierwsze wrażenie. Używam jQuery i CoffeeScript, i to doskonale do nich pasuje. Podkreślenie zaczyna się tam, gdzie kończy i do tej pory mnie nie zawiodło. A tak przy okazji, to tylko 3kb zminimalizowane.Sprawdź to:
źródło
Oprócz doskonałej i kompleksowej odpowiedzi ninjagecko, wystarczy spakować dwie tablice JS w „mimikę krotkową”:
Objaśnienie:
Ponieważ JavaScript nie ma
tuples
typu, funkcje krotek, list i zestawów nie miały wysokiego priorytetu w specyfikacji języka.W przeciwnym razie podobne zachowanie jest dostępne w prosty sposób poprzez mapę macierzy w JS> 1.6 . (
map
jest faktycznie często wdrażany przez producentów silników JS w wielu silnikach> JS 1.4, mimo że nie jest określony).Główną różnicą do Pythona
zip
,izip
... wynika zmap
„s stylu funkcjonalnym, ponieważmap
wymaga function-argument. Dodatkowo jest to funkcjaArray
-instance.Array.prototype.map
Zamiast tego można użyć , jeśli dodatkowa deklaracja dla danych wejściowych stanowi problem.Przykład:
Wynik:
Powiązana wydajność:
Korzystanie
map
zfor
pętli:Zobacz: Jaki jest najbardziej efektywny sposób łączenia [1,2] i [7,8] w [[1,7], [2,8]]
Uwaga: typy podstawowe, takie jak
false
iundefined
nie posiadają prototypowej hierarchii obiektów, a zatem nie ujawniajątoString
funkcji. Dlatego są wyświetlane jako puste na wyjściu.Ponieważ
parseInt
drugim argumentem jest podstawa podstawa / liczba, na którą należy przekonwertować liczbę, a ponieważmap
indeks jest przekazywany jako drugi argument do funkcji argumentu, używana jest funkcja otoki.źródło
aIn.map(function(e, i) {return [e, aOut[i]];})
Co jest nie tak?Array.prototype.map
powinno byćArray.prototype.map.call
, naprawiłem odpowiedź.Nowoczesny przykład ES6 z generatorem:
Po pierwsze, otrzymujemy listę iteracji jako
iterators
. Zwykle dzieje się to w sposób przejrzysty, ale tutaj robimy to wyraźnie, ponieważ wykonujemy krok po kroku, aż jeden z nich się wyczerpie. Sprawdzamy, czy którykolwiek z wyników (przy użyciu.some()
metody) w danej tablicy jest wyczerpany, a jeśli tak, przerywamy pętlę while.źródło
Wraz z innymi funkcjami podobnymi do Pythona,
pythonic
oferujezip
funkcję, z tą dodatkową korzyścią, że zwraca leniwy ocenianyIterator
, podobny do zachowania jego odpowiednika w Pythonie :Ujawnienie Jestem autorem i opiekunem Pythonic
źródło
Python ma dwie funkcje: zip i itertools.zip_longest. Implementacja w JS / ES6 wygląda następująco:
Implementacja zip Pythona na JS / ES6
Wyniki:
Implementacja zip_longest Pythona na JS / ES6
( https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest#itertools.zip_longest )
Wyniki:
źródło
Możesz ustawić funkcję narzędzia za pomocą ES6.
Jednak w powyższym rozwiązaniu długość pierwszej tablicy określa długość tablicy wyjściowej.
Oto rozwiązanie, w którym masz nad nim większą kontrolę. Jest to trochę skomplikowane, ale warto.
źródło
1. Moduł Npm:
zip-array
Znalazłem moduł npm, który można wykorzystać jako javascriptową wersję Pythona
zip
:zip-array - javascript równoważny z funkcją zip Pythona. Scala wartości każdej z tablic.
https://www.npmjs.com/package/zip-array
2.
tf.data.zip()
w Tensorflow.jsInną alternatywną opcją jest dla użytkowników Tensorflow.js: jeśli potrzebujesz
zip
funkcji w Pythonie do pracy z zestawami danych tensorflow w JavaScript, możesz użyćtf.data.zip()
Tensorflow.js.Dokumentacja tf.data.zip () w Tensorflow.js tutaj
źródło
Nie wbudowany w sam Javascript. Niektóre popularne frameworki JavaScript (takie jak Prototype) zapewniają implementację lub możesz napisać własną.
źródło
Jak @Brandon, polecam podkreślenia „s zip funkcji. Działa jednak tak
zip_longest
, jakbyundefined
w razie potrzeby dodawano wartości, aby zwrócić coś o długości najdłuższego wejścia.Użyłem tej
mixin
metody do rozszerzenia podkreślenia ozipShortest
, który działa jak Pythonzip
, w oparciu o własne źródło bibliotekizip
.Możesz dodać następujące elementy do wspólnego kodu JS, a następnie wywołać go tak, jakby był częścią podkreślenia:
_.zipShortest([1,2,3], ['a'])
zwraca[[1, 'a']]
, na przykład.źródło
Możesz zmniejszyć tablicę tablic i odwzorować nową tablicę, biorąc wynik indeksu tablicy wewnętrznej.
źródło
Odmiana leniwego generatora :
Oto klasyczny idiom pytona „n-group”
zip(*[iter(a)]*n)
:źródło
Mochikit biblioteka zapewnia to i wiele innych funkcji takich jak Python. twórca Mochikit jest także fanem Pythona, więc ma ogólny styl Pythona, a także otacza wywołania asynchroniczne w pokręconej strukturze.
źródło
Pobiegłem do tego w czystym JS, zastanawiając się, w jaki sposób wtyczki opublikowane powyżej wykonały zadanie. Oto mój wynik. Przedmówię to mówiąc, że nie mam pojęcia, jak stabilne będzie to w IE i tym podobnych. To tylko szybka makieta.
Nie jest kuloodporny, ale nadal jest interesujący.
źródło
console.log
naalert
.document.write()
jsfiddle.net/PyTWw/5To odcina linię od odpowiedzi opartej na iteratorze Ddi :
źródło
Jeśli nie masz nic przeciwko ES6:
źródło