Ik heb altijd ontdekt dat de functie range
ontbreekt in JavaScript omdat deze beschikbaar is in python en andere? Is er een beknopte manier om een reeks getallen te genereren in ES2015?
BEWERKEN: MIJN vraag verschilt van het genoemde duplicaat omdat het specifiek is voor ES2015 en niet voor ECMASCRIPT-5. Ik heb ook nodig dat het bereik begint bij 0 en geen specifiek startnummer (hoewel het goed zou zijn als dat er is)
Antwoord 1, autoriteit 100%
U kunt de spread-operator gebruiken op de toetsen van een nieuw gemaakte array.
[...Array(n).keys()]
of
Array.from(Array(n).keys())
De syntaxis Array.from()
is nodig als u met TypeScript werkt
Antwoord 2, autoriteit 35%
Ik heb ook nog een intuïtieve manier gevonden om Array.from
te gebruiken:
const range = n => Array.from({length: n}, (value, key) => key)
Deze functie range
retourneert nu alle getallen beginnend van 0 tot n-1
Een aangepaste versie van het bereik om start
en end
te ondersteunen is:
const range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
BEWERKEN
Zoals gesuggereerd door @marco6, kun je dit als een statische methode gebruiken als dit geschikt is voor jouw gebruik
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
en gebruik het als
Array.range(3, 9)
Antwoord 3, autoriteit 13%
Met Delta/Step
kleinste en oneliner
[...Array(N)].map((_, i) => from + i * step);
Voorbeelden en andere alternatieven
[...Array(10)].map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10)).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Array(10).fill(0).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array(10).fill().map((_, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Bereik Functie:
const range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
range(0, 9, 2);
//=> [0, 2, 4, 6, 8]
// can also assign range function as static method in Array class (but not recommended )
Array.range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]
Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.range(2, 10, -1);
//=> []
Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
als iterators
class Range {
constructor(total = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
for (let i = 0; i < total; yield from + i++ * step) {}
};
}
}
[...new Range(5)]; // Five Elements
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Five Elements With Step 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
Alleen als generatoren
const Range = function* (total = 0, step = 1, from = 0) {
for (let i = 0; i < total; yield from + i++ * step) {}
};
Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]
[...Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
// Lazy loaded way
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
Van-Naar met stappen/delta
iterators gebruiken
class Range2 {
constructor(to = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
}
}
[...new Range2(5)]; // First 5 Whole Numbers
//=> [0, 1, 2, 3, 4, 5]
[...new Range2(5, 2)]; // From 0 to 5 with step 2
//=> [0, 2, 4]
[...new Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
generatoren gebruiken
const Range2 = function* (to = 0, step = 1, from = 0) {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
[...Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
Voor typoscript
interface _Iterable extends Iterable<{}> {
length: number;
}
class _Array<T> extends Array<T> {
static range(from: number, to: number, step: number): number[] {
return Array.from(
<_Iterable>{ length: Math.floor((to - from) / step) + 1 },
(v, k) => from + k * step
);
}
}
_Array.range(0, 9, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
Bijwerken
class _Array<T> extends Array<T> {
static range(from: number, to: number, step: number): number[] {
return [...Array(Math.floor((to - from) / step) + 1)].map(
(v, k) => from + k * step
);
}
}
_Array.range(0, 9, 1);
Bewerken
class _Array<T> extends Array<T> {
static range(from: number, to: number, step: number): number[] {
return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
(v, k) => from + k * step
);
}
}
_Array.range(0, 9, 1);
Antwoord 4, autoriteit 7%
Voor nummers 0 tot 5
[...Array(5).keys()];
=> [0, 1, 2, 3, 4]
Antwoord 5, autoriteit 5%
Veel van deze oplossingen bouwen voort op het instantiëren van echte Array-objecten, die de klus voor veel gevallen kunnen klaren, maar die geen ondersteuning bieden voor gevallen zoals range(Infinity)
. Je zou een eenvoudige generator kunnen gebruiken om deze problemen te vermijden en oneindige reeksen te ondersteunen:
function* range( start, end, step = 1 ){
if( end === undefined ) [end, start] = [start, 0];
for( let n = start; n < end; n += step ) yield n;
}
Voorbeelden:
Array.from(range(10)); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Array.from(range(10, 20)); // [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
i = range(10, Infinity);
i.next(); // { value: 10, done: false }
i.next(); // { value: 11, done: false }
i.next(); // { value: 12, done: false }
i.next(); // { value: 13, done: false }
i.next(); // { value: 14, done: false }
Antwoord 6, autoriteit 4%
Dus in dit geval zou het fijn zijn als het Number-object zich zou gedragen als een Array-object met de spread-operator.
Bijvoorbeeld Arrayobject gebruikt met de spread-operator:
let foo = [0,1,2,3];
console.log(...foo) // returns 0 1 2 3
Het werkt zo omdat het Array-object een ingebouwde iterator heeft.
In ons geval hebben we een Numberobject nodig om een vergelijkbare functionaliteit te hebben:
[...3] //should return [0,1,2,3]
Om dat te doen, kunnen we voor dat doel eenvoudig Number iterator maken.
Number.prototype[Symbol.iterator] = function *() {
for(let i = 0; i <= this; i++)
yield i;
}
Het is nu mogelijk om bereiken van 0 tot N te creëren met de spread-operator.
[…N] // geeft nu 0 … N array terug
http://jsfiddle.net/01e4xdv5/4/
Proost.
Antwoord 7
Je kunt een generatorfunctie gebruiken, die het bereik alleen lui creëert als dat nodig is:
function* range(x, y) {
while (true) {
if (x <= y)
yield x++;
else
return null;
}
}
const infiniteRange = x =>
range(x, Infinity);
console.log(
Array.from(range(1, 10)) // [1,2,3,4,5,6,7,8,9,10]
);
console.log(
infiniteRange(1000000).next()
);
Antwoord 8
Bereik met stap ES6, dat werkt vergelijkbaar met python list(range(start, stop[, step]))
:
const range = (start, stop, step = 1) => {
return [...Array(stop - start).keys()]
.filter(i => !(i % Math.round(step)))
.map(v => start + v)
}
Voorbeelden:
range(0, 8) // [0, 1, 2, 3, 4, 5, 6, 7]
range(4, 9) // [4, 5, 6, 7, 8]
range(4, 9, 2) // [4, 6, 8]
range(4, 9, 3) // [4, 7]
Antwoord 9
Delta ondersteunen
const range = (start, end, delta) => {
return Array.from(
{length: (end - start) / delta}, (v, k) => (k * delta) + start
)
};
Antwoord 10
Wat dacht je van gewoon in kaart brengen ….
Array(n).map((value, index) ….) is 80% van de weg ernaartoe. Maar om de een of andere vreemde reden werkt het niet. Maar er is een oplossing.
Array(n).map((v,i) => i) // does not work
Array(n).fill().map((v,i) => i) // does dork
Voor een bereik
Array(end-start+1).fill().map((v,i) => i + start) // gives you a range
Vreemd, deze twee iterators retourneren hetzelfde resultaat: Array(end-start+1).entries()
en Array(end-start+1).fill().entries()
Antwoord 11
Je kunt het ook doen met een oneliner met opstapondersteuning zoals deze:
((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)
Het resultaat is [0, 1, 2, 3, 4, 5, 6 ,7 ,8 ,9]
.