W PHP możesz zrobić ...
range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
Oznacza to, że istnieje funkcja, która pozwala uzyskać zakres liczb lub znaków, przekraczając górną i dolną granicę.
Czy jest coś wbudowanego w JavaScript w tym celu? Jeśli nie, jak miałbym to wdrożyć?
$R
funkcję, ale poza tym tak naprawdę nie sądzę.Array.from("ABC") //['A', 'B', 'C']
Jest to najbliższa rzecz, jaką mogę znaleźć w drugiej części pytania.split("")
tam również skorzystaćArray.apply(null, { length: 10 }).map(eval.call, Number)
Odpowiedzi:
Liczby
Iteracja postaci
Iteracja
Jako funkcje
Jako funkcje wpisane
_.range()
funkcja lodash.jsStare przeglądarki inne niż es6 bez biblioteki:
(Kredyt ES6 dla Nilsa Petersohna i innych komentujących)
źródło
(new Array(5)).map(function (value, index) { return index; })
nie działa? To zwraca[undefined × 5]
mi w Chrome DevTools.map()
ani z jednym z jego przyjaciół.Array(5).fill()
jest również możliwy do zmapowaniaW przypadku liczb można użyć ES6
Array.from()
, który działa we wszystkim obecnie oprócz IE:Krótsza wersja:
Dłuższa wersja:
który tworzy tablicę od 0 do 19 włącznie. Można to dalej skrócić do jednej z tych form:
Można również określić dolne i górne granice, na przykład:
Artykuł opisujący to bardziej szczegółowo: http://www.2ality.com/2014/05/es6-array-methods.html
źródło
Array.from()
metoda i szybsze niż oba:Array(20).fill().map((_, i) => i)
Array.from({length: end - start}, (v, k) => k + start)
undefined
, więcfill()
(bez argumentu) samo w sobie nie jest błędne . Wartość wypełnienia nie jest używana w tym rozwiązaniu, więc jeśli chcesz, możeszfill(0)
zapisać kilka znaków.Moja nowa ulubiona forma ( ES2015 )
A jeśli potrzebujesz funkcji z
step
parametrem:źródło
stop
nie jest faktycznie pozycją zatrzymania / końca, ale liczbą / odległością. (bez obrazy, tylko po to, by uświadomić ludziom literówkę)Array(Math.ceil((stop - start) / step) + 1)
, potrzebuje+1
na końcu, aby naprawdę naśladować zachowanie „integracyjne” php.range
metodę. Wszystkie pozostałe powyżej tego (z wyjątkiem lodasha_.range
) implementują podstawowe iteratory zamiast rzeczywistej funkcji zakresu z startem, stopem i krokiemOto moje 2 centy:
źródło
Działa dla znaków i cyfr, przechodząc do przodu lub do tyłu z opcjonalnym krokiem.
jsFiddle .
Jeśli zależy Ci na rozszerzeniu typów natywnych, przypisz je do
Array.range
.Pokaż fragment kodu
źródło
Prosta funkcja zasięgu:
Aby uwzględnić typ danych BitInt, można włączyć sprawdzanie, upewniając się, że wszystkie zmienne są takie same
typeof start
:Aby usunąć wartości wyższe niż zdefiniowane
stop
np.range(0,5,2)
Będzie zawierać6
, co nie powinno być.źródło
step != 1
Thewhile
warunek musi braćstep
pod uwagę. Moja zaktualizowana wersja zstep
wartością domyślną : zakres funkcji (start, stop, krok) {step = step || 1 var a = [start], b = start; while ((b + step) <stop) {console.log ("b:" + b + ". a:" + a + "."); b + = krok; a.push (b); } zwróć a; }(step || 1)
.źródło
Array
prototypowania.undefined method toUpperCase to etc
:!OK, w JavaScript nie mamy
range()
funkcji takiej jak PHP , więc musimy stworzyć funkcję, która jest dość łatwa, piszę dla ciebie kilka funkcji jednowierszowych i oddzielam je dla liczb i alfabetów, jak poniżej:dla liczb :
i nazwij to tak:
dla alfabetów :
i nazwij to tak:
źródło
Array(end - start + 1)
iArray(end.charCodeAt(0) - start.charCodeAt(0) + 1)
.Przydatna funkcja, aby załatwić sprawę, uruchom poniższy fragment kodu
oto jak go użyć
zakres (Start, Koniec, Krok = 1, Przesunięcie = 0);
range(5,10) // [5, 6, 7, 8, 9, 10]
range(10,5) // [10, 9, 8, 7, 6, 5]
range(10,2,2) // [10, 8, 6, 4, 2]
range(5,10,0,-1) // [6, 7, 8, 9] not 5,10 themselves
range(5,10,0,1) // [4, 5, 6, 7, 8, 9, 10, 11]
range(5,10,0,-2) // [7, 8]
range(10,0,2,2) // [12, 10, 8, 6, 4, 2, 0, -2]
mam nadzieję, że okażą się przydatne.
A oto jak to działa.
Zasadniczo najpierw obliczam długość wynikowej tablicy i tworzę tablicę wypełnioną zerami do tej długości, a następnie wypełniam ją wymaganymi wartościami
(step || 1)
=> A inne tego typu oznaczają użycie wartościstep
i jeśli nie zostało podane, użyj1
zamiast tego(Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1)
aby ją uprościć (różnica * przesunięcie w obu kierunkach / krokach)new Array(length).fill(0);
check tutaj[0,0,0,..]
długości. Mapujemy go i zwracamy nową tablicę z wartościami, których potrzebujemy, używającArray.map(function() {})
var direction = start < end ? 1 : 0;
Oczywiście, jeślistart
nie jest mniejszy niżend
musimy cofnąć się. Mam na myśli przejście od 0 do 5 lub odwrotniestartingPoint
+stepSize
*index
daje nam potrzebną wartośćźródło
źródło
_
to tylko nazwa argumentu w wywołaniu zwrotnym mapowania. Wiesz, w niektórych językach używałbyś tego_
jako nazwy, aby wskazać, że zmienna nie jest używana._
nie przekazuje się argumentów dorange
. Dlaczego nie?Korzystanie z funkcji rozkładania i strzałek Harmony :
Przykład:
źródło
--- AKTUALIZACJA (Dzięki @lokhmakov dla uproszczenia) ---
Kolejna wersja korzystająca z generatorów ES6 (zobacz świetną odpowiedź Paolo Moretti z generatorami ES6 ):
Lub, jeśli potrzebujemy tylko iteracji, to:
--- Kod ORGINAL: ---
i
źródło
const range = (x, y) => Array.from(function* () { while (x <= y) yield x++; }())
Przeprowadziłem badania dotyczące różnych funkcji zakresu. Sprawdź porównanie jsperf różnych sposobów wykonywania tych funkcji. Z pewnością nie jest to lista idealna ani wyczerpująca, ale powinna pomóc :)
Zwycięzcą jest...
Z technicznego punktu widzenia nie jest to najszybszy firefox, ale nadrabia to szalona różnica prędkości (imho) na chromie.
Ciekawym spostrzeżeniem jest także o ile szybszy jest chrom z tymi funkcjami tablicowymi niż Firefox. Chrome jest co najmniej 4 lub 5 razy szybszy .
źródło
Standardowy Javascript nie ma wbudowanej funkcji do generowania zakresów. Niektóre frameworki javascript dodają obsługę takich funkcji, lub, jak zauważyli inni, zawsze możesz uruchomić własne.
Jeśli chcesz dwukrotnie sprawdzić, ostatecznym zasobem jest standard ECMA-262 .
źródło
Możesz użyć lodash lub Undescore.js
range
:Alternatywnie, jeśli potrzebujesz tylko kolejnego zakresu liczb całkowitych, możesz zrobić coś takiego:
W ES6
range
można zaimplementować za pomocą generatorów :Ta implementacja oszczędza pamięć podczas iteracji dużych sekwencji, ponieważ nie musi zmaterializować wszystkich wartości w tablicy:
źródło
Array.from
do konwersji generatorów na instancje tablicowe i sprawdzenia danych wyjściowych.Ciekawym wyzwaniem byłoby napisanie najkrótszej funkcji, aby to zrobić. Rekurencja na ratunek!
Na dużych zasięgach zwykle działa powoli, ale na szczęście komputery kwantowe są tuż za rogiem.
Dodatkową zaletą jest to, że jest zaciemniające. Ponieważ wszyscy wiemy, jak ważne jest ukrywanie naszego kodu przed wścibskimi oczami.
Aby całkowicie i całkowicie zaciemnić funkcję, wykonaj następujące czynności:
źródło
const range = (a, b) => (a>=b) ? [] : [a, ...range(a+1, b)]
przy użyciu składni ES6const range = (a, b, Δ = 1) => (a > b) ? [] : [a, ...range(a + Δ, b, Δ)];
. Głosowałem również za odpowiedzią na całą odpowiedź.To może nie być najlepszy sposób. Ale jeśli chcesz uzyskać zakres liczb w jednym wierszu kodu. Na przykład 10-50
Gdzie 40 to (koniec - początek), a 10 to początek. To powinno zwrócić [10, 11, ..., 50]
źródło
Kodowałbym coś takiego:
Zachowuje się podobnie do zakresu Python:
źródło
Raczej minimalistyczna implementacja mocno wykorzystująca ES6 może zostać utworzona w następujący sposób, zwracając szczególną uwagę na
Array.from()
metodę statyczną:źródło
getRange()
funkcję. W szczególności chciałem uchwycić przypadki brzegowe, które mogą być nieradowane w powyższym wariancie bez kości. Dodatkowo dodałem obsługę zakresów alfanumerycznych. Innymi słowy, wywołanie go za pomocą dwóch dostarczonych danych wejściowych, takich jak'C'
i'K'
(w tej kolejności), zwraca tablicę, której wartości to sekwencyjny zestaw znaków od litery „C” (włącznie) do litery „K” (wyłącznie):getRange('C', 'K'); // => ["C", "D", "E", "F", "G", "H", "I", "J"]
new
słowa kluczowegorange(start,end,step)
: Z iteratorami ES6Pytasz tylko o górną i dolną granicę. Tutaj tworzymy również krok.
Możesz łatwo stworzyć
range()
funkcję generatora, która może działać jako iterator. Oznacza to, że nie musisz wstępnie generować całej tablicy.Teraz możesz utworzyć coś, co wstępnie generuje tablicę z iteratora i zwraca listę. Jest to przydatne w przypadku funkcji, które akceptują tablicę. Do tego możemy użyć
Array.from()
Teraz możesz łatwo wygenerować tablicę statyczną,
Ale gdy coś wymaga iteratora (lub daje opcję korzystania z iteratora), możesz z łatwością go utworzyć.
Specjalne notatki
R.range
podobnie jak Lodashźródło
Choć nie jest to z PHP , ale imitacja
range
z Pythonem .źródło
Jeśli chodzi o generowanie tablicy numerycznej dla danego zakresu, używam tego:
Oczywiście nie będzie działać dla tablic alfabetycznych.
źródło
array = []
w pętli może nie dać ci tego, czego chcesz.[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
, oczekiwałbym tylko pierwszej połowy tej tablicy.Korzystanie z generatorów Harmony , obsługiwanych przez wszystkie przeglądarki oprócz IE11 :
Przykłady
brać
Przykład 1.
take
zajmuje tylko tyle, ile może dostaćtake(10, range( {from: 100, step: 5, to: 120} ) )
zwroty
[100, 105, 110, 115, 120]
Przykład 2
to
nie jest koniecznetake(10, range( {from: 100, step: 5} ) )
zwroty
[100, 105, 110, 115, 120, 125, 130, 135, 140, 145]
Weź wszystko
Przykład 3
from
nie jest koniecznetakeAll( range( {to: 5} ) )
zwroty
[0, 1, 2, 3, 4, 5]
Przykład 4
takeAll( range( {to: 500, step: 100} ) )
zwroty
[0, 100, 200, 300, 400, 500]
Przykład 5
takeAll( range( {from: 'z', to: 'a'} ) )
zwroty
["z", "y", "x", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"]
źródło
for
klauzuli poprawiłby tutaj czytelność.... większy zasięg za pomocą funkcji generatora.
Mam nadzieję, że to się przyda.
źródło
Mój współpracujący z nami golfista wymyślił to (ES6), w tym:
nie obejmuje:
źródło
możesz użyć
lodash
funkcji_.range(10)
https://lodash.com/docs#rangeźródło
d3 ma również wbudowaną funkcję zakresu. Zobacz https://github.com/mbostock/d3/wiki/Arrays#d3_range :
Przykład:
źródło
Pełna implementacja ES6 przy użyciu sygnatury zasięgu ([start,] stop [, krok]):
Jeśli chcesz automatyczne stopniowanie ujemne, dodaj
Lub bardziej minimalistycznie:
Jeśli masz ogromny zasięg, spójrz na podejście generatora Paolo Morettiego
źródło
!stop
siętypeof stop === 'undefined'
, a następnie zastąpićint
zMath.floor
, i dodać czekif (start > stop && step > 0)
(w przeciwnym razie,range(-3, -10)
zgłasza wyjątek zamiast robić coś Sane (albo przerzucanie znak kroku lub powrotu[]
)). W przeciwnym razie dobrze!Jest na to moduł npm bereich („bereich” to niemieckie słowo określające „zasięg”). Wykorzystuje nowoczesne iteratory JavaScript, dzięki czemu można go używać na różne sposoby, takie jak:
Obsługuje również zakresy malejące (po prostu zamieniając
min
imax
), a także obsługuje kroki inne niż1
.Oświadczenie: Jestem autorem tego modułu, więc proszę o odpowiedź z odrobiną soli.
źródło
Ten działa również w odwrotnej kolejności.
źródło