Zawsze range
brakowało mi tej funkcji w JavaScript, ponieważ jest dostępna w Pythonie i innych? Czy jest jakiś zwięzły sposób na wygenerowanie zakresu liczb w ES2015?
EDYCJA: MOJE pytanie różni się od wspomnianego duplikatu, ponieważ jest specyficzne dla ES2015, a nie ECMASCRIPT-5. Potrzebuję również, aby zakres zaczynał się od 0, a nie konkretny numer początkowy (choć byłoby dobrze, gdyby tak było)
javascript
arrays
ecmascript-6
Aditya Singh
źródło
źródło
[...Array(n).keys()]
.[...Array(5)].map((_,i) => i+1)
Odpowiedzi:
Możesz użyć operatora spreadu na kluczach świeżo utworzonej tablicy.
[...Array(n).keys()]
lub
Array.from(Array(n).keys())
Array.from()
Składnia jest konieczne, jeśli pracuje z maszynopisźródło
function range (start, end) { return [...Array(1+end-start).keys()].map(v => start+v) }
Array.from(Array(n).keys())
.[...Array(n).keys()]
nie działa w programie Typescript? Czy jest to celowe odstępstwo od innych implementacji JS?Array(5).keys().slice()
i plasterek nie jest metodą iteratora tablicy. Oto przykład tego, że nie działa typescriptlang.org/play/ ...Znalazłem też jeden bardziej intuicyjny sposób, używając
Array.from
:Teraz ta
range
funkcja zwróci wszystkie liczby zaczynające się od 0 do n-1Zmodyfikowana wersja zakresu do obsługi
start
iend
to:EDYCJA Zgodnie z sugestią @ marco6, możesz ustawić to jako metodę statyczną, jeśli pasuje do twojego przypadku użycia
i używaj go jako
źródło
interface ArrayConstructor { range(n: number): number[]; }
Array.range = n => Array.from({length: n}, (value, key) => key);
A potem wszędzieArray.range(x)...
[ts] Property 'range' does not exist on type 'ArrayConstructor'
. thouths?Z Delta
W przypadku javascript
Dla maszynopisu
Aktualizacja
Edytować
źródło
Array.from(Array(~~((to - from) / step) + 1).keys())
Dla liczb od 0 do 5
źródło
Wiele z tych rozwiązań opiera się na tworzeniu wystąpień rzeczywistych obiektów Array, które mogą wykonać zadanie w wielu przypadkach, ale nie obsługują takich przypadków
range(Infinity)
. Możesz użyć prostego generatora, aby uniknąć tych problemów i obsługiwać nieskończone sekwencje:Przykłady:
źródło
Tak więc w tym przypadku byłoby miło, gdyby Number obiekt zachowywał się jak obiekt Array z operatorem spreadu.
Na przykład obiekt Array używany z operatorem spread:
Działa to w ten sposób, ponieważ obiekt Array ma wbudowany iterator.
W naszym przypadku potrzebujemy obiektu Number, aby miał podobną funkcjonalność:
Aby to zrobić, możemy po prostu utworzyć w tym celu iterator liczb.
Teraz za pomocą operatora spread można tworzyć zakresy od 0 do N.
http://jsfiddle.net/01e4xdv5/4/
Twoje zdrowie.
źródło
Możesz użyć funkcji generatora, która leniwie tworzy zakres tylko wtedy, gdy jest to potrzebne:
Możesz użyć funkcji generatora wyższego rzędu, aby zmapować
range
generator:Jeśli jesteś nieustraszony, możesz nawet uogólnić podejście generatora, aby zająć się znacznie szerszym zakresem (gra słów zamierzona):
Należy pamiętać, że generatory / iteratory są z natury stanowe, to znaczy, że istnieje niejawna zmiana stanu przy każdym wywołaniu
next
. Stan jest błogosławieństwem mieszanym.źródło
Zakres z krokiem ES6, który działa podobnie do Pythona
list(range(start, stop[, step]))
:Przykłady:
źródło
Aby wspierać delta
źródło
Możesz to również zrobić za pomocą jednej wkładki ze wsparciem stopniowym, takim jak ten:
((from, to, step) => ((add, arr, v) => add(arr, v, add))((arr, v, add) => v < to ? add(arr.concat([v]), v + step, add) : arr, [], from))(0, 10, 1)
Wynik jest
[0, 1, 2, 3, 4, 5, 6 ,7 ,8 ,9]
.źródło
Ta funkcja zwróci sekwencję liczb całkowitych.
źródło
w maszynie
źródło
Array.from
i składni rozprzestrzeniania. A potem jest dokładnie taka sama, jak istniejąca odpowiedź.[...Array(n).keys()]
że nie działa w maszynopisie.Array.from(Array(n).keys())
. Jestem prawie pewien, że powinno działać, ale do czego służy literał ze składnią rozprzestrzeniania?Oto kolejna odmiana, której nie używa
Array
.źródło
Generatory pozwalają teraz na leniwe generowanie sekwencji liczb i używanie mniejszej ilości pamięci dla dużych zakresów.
Podczas gdy pytanie konkretnie dotyczy ES2015, spodziewam się, że wielu użytkowników maszynopisów skończy tutaj, a konwersja do ES jest prosta ...
Pierwsze dwie deklaracje funkcji mają na celu dostarczenie bardziej pouczających sugestii uzupełniania w twoim IDE.
źródło
Co powiesz na mapowanie…
Array (n) .map ((wartość, indeks) ...) jest tam 80%. Ale z jakiegoś dziwnego powodu to nie działa. Ale jest obejście.
Dla zakresu
Co dziwne, te dwie iteratory zwracają ten sam wynik:
Array(end-start+1).entries()
iArray(end-start+1).fill().entries()
źródło