Does JavaScript have a method like "range()" to generate a range within the supplied bounds?

1,144,905

Solution 1

It works for characters and numbers, going forwards or backwards with an optional step.

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

jsFiddle.

If augmenting native types is your thing, then assign it to Array.range.

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

console.log(range("A", "Z", 1));
console.log(range("Z", "A", 1));
console.log(range("A", "Z", 3));


console.log(range(0, 25, 1));

console.log(range(0, 25, 5));
console.log(range(20, 5, 5));

Solution 2

Numbers

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]

Character iteration

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"

Iteration

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"

As functions

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

As typed functions

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

lodash.js _.range() function

_.range(10);
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
 => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
 => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"

Old non es6 browsers without a library:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]

console.log([...Array(5).keys()]);

(ES6 credit to nils petersohn and other commenters)

Solution 3

For numbers you can use ES6 Array.from(), which works in everything these days except IE:

Shorter version:

Array.from({length: 20}, (x, i) => i);

Longer version:

Array.from(new Array(20), (x, i) => i);​​​​​​

which creates an array from 0 to 19 inclusive. This can be further shortened to one of these forms:

Array.from(Array(20).keys());
// or
[...Array(20).keys()];

Lower and upper bounds can be specified too, for example:

Array.from(new Array(20), (x, i) => i + *lowerBound*);

An article describing this in more detail: http://www.2ality.com/2014/05/es6-array-methods.html

Solution 4

My new favorite form (ES2015)

Array(10).fill(1).map((x, y) => x + y)

And if you need a function with a step param:

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)

Another possible implementation suggested by the MDN docs:

// Sequence generator function 
// (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => 
  Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step))

Solution 5

Here's my 2 cents:

function range(start, end) {
  return Array.apply(0, Array(end - 1))
    .map((element, index) => index + start);
}
Share:
1,144,905
user3167101
Author by

user3167101

I like to make stuff. Check out my blog. You can email me at alex at my domain. My dotfiles, if you're curious :)

Updated on February 10, 2022

Comments

  • user3167101
    user3167101 about 2 years

    In PHP, you can do...

    range(1, 3); // Array(1, 2, 3)
    range("A", "C"); // Array("A", "B", "C")
    

    That is, there is a function that lets you get a range of numbers or characters by passing the upper and lower bounds.

    Is there anything built-in to JavaScript natively for this? If not, how would I implement it?

    • Yi Jiang
      Yi Jiang over 13 years
      Prototype.js has the $R function, but other than that I don't really think so.
    • btk
      btk about 9 years
      This (related) question has some excellent answers: stackoverflow.com/questions/6299500/…
    • Andrew_1510
      Andrew_1510 almost 8 years
      Array.from("ABC") //['A', 'B', 'C'] This is the closest thing I can find for the second part of the question.
    • user3167101
      user3167101 almost 8 years
      @Andrew_1510 You could use split("") there also
    • csharpfolk
      csharpfolk almost 8 years
      When lover bound is zero this oneliner: Array.apply(null, { length: 10 }).map(eval.call, Number)
    • Benj
      Benj about 7 years
      See stackoverflow.com/a/38213213/1579667 -> Array.from({length: N}, (v, k) => k+1);
    • Evan Carroll
      Evan Carroll about 5 years
    • KyleMit
      KyleMit about 5 years
    • Anurag Hazra
      Anurag Hazra almost 4 years
      btw just for info there's a tc39 proposal for Number.range, which is stage-1 at the moment github.com/tc39/proposal-Number.range
    • windmaomao
      windmaomao over 3 years
      there's no point implementing range, instead we should focus on how to create an array with fixed size (and type). That's a more relevant problem to solve.
    • Dave F
      Dave F about 3 years
      No, but you can define the function using: const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step)); (see 'Sequence generator (range)' from MSDN) NOTE: This function only works if all parameters are specified (ie. range(1,5,1) produces the array [1,2,3,4,5], but range(1,5) produces an empty array)
    • totymedli
      totymedli over 2 years
      All of the answers are full off witty functional solutions while this is a trivial thing to implement with a regular loop. Everybody tries to be clever and short while the most important thing is that the code is readable and easy to understand.
  • Lodewijk
    Lodewijk almost 11 years
    Because if it's useful anywhere it is probably useful in JS. (JS can do functional programming type stuff, which can benefit from a range(0 statement. That and a thousand other reasons it might be useful in some semirare case)
  • Xotic750
    Xotic750 almost 11 years
    Edited with my suggestions :)
  • Justin Johnson
    Justin Johnson almost 10 years
    +1 for the approach. To @alex's point, not having ternary operations (especially not nested) in the for clause would improve readability here.
  • Eric Hartford
    Eric Hartford over 9 years
    An example, say I want to pregenerate palettes of size 1, 2, 3, 4, 5, etc. I'd do something like var palettes = range(1, 20).map(function(n){return generatePalette(n);});
  • user3167101
    user3167101 almost 9 years
    Setting array = [] inside the loop may not give you what you want.
  • jhaskell
    jhaskell almost 9 years
    @alex, thank you. You're right, I also forgot to increment the "start" parameter on each pass of the loop. It's fixed now.
  • user3167101
    user3167101 almost 9 years
    It still won't produce the desired output, if I want range 5-10, it will give me [5, 6, 7, 8, 9, 10, 11, 12, 13, 14], I would expect only the first half of that array.
  • jhaskell
    jhaskell almost 9 years
    @alex, thank you again, I had not considered a length constraint based on input. See updated version.
  • user3167101
    user3167101 over 8 years
    1. Your check() missed a chance to short circuit and early return, 2. You have a few redundant variables, 3. Using document.write() makes the function pretty useless for most applications
  • Shawn Mehan
    Shawn Mehan over 8 years
    As @btk posted, there are many approaches in this related post
  • amergin
    amergin over 8 years
    Useful Lodash function, but does not answer the second part of this question: how to create a character range.
  • user3167101
    user3167101 over 8 years
    Does a lot of unnecessary work each iteration though.
  • joews
    joews over 8 years
    The ES6 part is now the correct answer to this question. I would recommend removing the other parts, which are covered by other answers.
  • Delapouite
    Delapouite over 8 years
    The first example can even be simplified to [...Array(20).keys()]
  • monsto
    monsto over 8 years
    PLUS UNO for usable and readable. Best code snippet I've seen in a long time.
  • Lewis
    Lewis over 8 years
    Any idea why simply using (new Array(5)).map(function (value, index) { return index; }) wouldn't work? This returns [undefined × 5] for me in Chrome DevTools.
  • user3167101
    user3167101 over 8 years
    @Lewis Because an array defined with that has empty slots that won't be iterated over with map() or one of its friends.
  • Henry H.
    Henry H. over 8 years
    that's the best answer!
  • user3167101
    user3167101 over 8 years
    typeof on a variable guaranteed to be set can be replaced with a strict equality check with undefined or void 0 if you're paranoid and not in strict mode.
  • Andreas Louv
    Andreas Louv about 8 years
    Use [...Array(e-b)] while you are at it.
  • Stu Cox
    Stu Cox about 8 years
    Slightly more succinct than the Array.from() method, and faster than both: Array(20).fill().map((_, i) => i)
  • PascalVKooten
    PascalVKooten about 8 years
    Handy, most certainly. Simple? I beg to differ; regardless that you make it a one liner. Coming from Python this is a shock.
  • azerafati
    azerafati about 8 years
    @PascalvKooten, yeah of course it would have been great if there was built-in method for that like python I guess, but this was the simplest one I could come by. And it has proven to be handy in my projects.
  • user3167101
    user3167101 about 8 years
    var highest = Math.max.apply(null, array).
  • user3167101
    user3167101 about 8 years
    or Math.max(...array)
  • abuduba
    abuduba about 8 years
    What's wrong with descending order? range[4, 2] should return sequence [4, 3, 2]. BTW, it assumes the input array might be any length but you pick only two values (array.reduce is an overkill in this case), suppose createRange(a, b) would be more handy here
  • user3167101
    user3167101 about 8 years
    Best performance has a few things that could be improved, such as setting step to a default value outside of the loop.
  • Klesun
    Klesun about 8 years
    @nikkwong, the _ is just a name of argument in the mapping callback. You know, in some languages you would use the _ as a name to point out that the variable is not used.
  • nikk wong
    nikk wong about 8 years
    Here though, _ isn't passed through the arguments to range. Why not?
  • nils petersohn
    nils petersohn about 8 years
    Array.from(Array(5).keys())
  • jib
    jib about 8 years
    @Delapouite Awesome! You should make that a separate answer, and I'll vote for it! It's also the perfect answer to this duplicate.
  • Aditya Singh
    Aditya Singh almost 8 years
    @Delapouite @jib And this as well: Array.from({length: end - start}, (v, k) => k + start)
  • Rafael Xavier
    Rafael Xavier almost 8 years
    Very neat! Although, it's important to note it doesn't work on any IE or Opera.
  • jocull
    jocull over 7 years
    Be aware that you cannot use Array.from in IE (but it probably works in Edge) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • Freez
    Freez over 7 years
    You also can use the spread operator [...new Array(5)] , only working with modern browser or using transpiler (ES2015)
  • I_do_python
    I_do_python over 7 years
    You just reinvented array.slice(1,5).
  • Fuji
    Fuji over 7 years
    The spread operator is already used in the ES6 example. [...new Array(5)] prints 5 undefined's
  • Neurotransmitter
    Neurotransmitter over 7 years
    Nifty if you'd like to create array of empty subarrays too (var matrix = Array.from(new Array(3), () => []);).
  • chukko
    chukko over 7 years
    slice has a slight disadvantage of having side effect - modifying the passed array (which wouldnt harm in example above, but might in real life code)
  • Ahmed Fasih
    Ahmed Fasih over 7 years
    Replace !stop with typeof stop === 'undefined', then replace int with Math.floor, and add a check if (start > stop && step > 0) (otherwise, range(-3, -10) throws an exception instead of doing something sane (either flipping the sign of step or returning [])). Otherwise, good!
  • Anona112
    Anona112 over 7 years
    generators are somewhat strange if used outside a loop though: x=range(1, 10);//{} x;//{}// looks like an empty map WTF!?! x.next().value;// OK 1 ;x[3] // undefined, only with real array
  • Paolo Moretti
    Paolo Moretti over 7 years
    @Anona112 you can use Array.from to convert generators to array instances and inspect the output.
  • Madbreaks
    Madbreaks over 7 years
    Posting a painfully complex code snippet like that, especially as a one-liner and with no explanation of how it works? Poor example of a good SO answer, regardless of whether or not it "works".
  • Madbreaks
    Madbreaks over 7 years
    This answer needs explanation, as it stands its a poor fit for SO.
  • azerafati
    azerafati over 7 years
    @Madbreaks, yea you're right. I've been naive to make it a one liner. just wanted to give everyone a quick and easy solution
  • nafg
    nafg over 7 years
    Short != simple, but simpler is better. Here's an easier to read version: const range = (a, b) => (a>=b) ? [] : [a, ...range(a+1, b)], using ES6 syntax
  • IsenrichO
    IsenrichO about 7 years
    As a side note, I've created a Gist in which I made an "enhanced" getRange() function of sorts. In particular, I aimed to capture edge cases that might be unaddressed in the bare-bones variant above. Additionally, I added support for alphanumeric ranges. In other words, calling it with two supplied inputs like 'C' and 'K' (in that order) returns an array whose values are the sequential set of characters from the letter 'C' (inclusive) through the letter 'K' (exclusive): getRange('C', 'K'); // => ["C", "D", "E", "F", "G", "H", "I", "J"]
  • nils petersohn
    nils petersohn about 7 years
    Array(5).fill() is also mappable
  • Serge Intern
    Serge Intern about 7 years
    Here's a worst way to achieve this: Array.apply(null, new Array(5)).map(Number.call.bind(Number))
  • mjwrazor
    mjwrazor almost 7 years
    I never knew D3 existed. Not going to use their range method but will be using this package.
  • mjwrazor
    mjwrazor almost 7 years
    Not the fastest though.
  • mjwrazor
    mjwrazor almost 7 years
    +1 for the fastest. with an array of -36768 - 36768, took 3ms, 2nd place was 13 ms and has IDE red lines.
  • user3167101
    user3167101 almost 7 years
    Array.prototype.reverse() is expensive though for any decently long range.
  • mjwrazor
    mjwrazor almost 7 years
    @alex I will retract my statement on that then. But I will leave the block as is since adding in < | > | === | logic would be rather simple. I did say easily adjustable.
  • binaryfunt
    binaryfunt over 6 years
    Note that this was compared against range functions that included a step size parameter
  • Rico Kahler
    Rico Kahler over 6 years
    Array.from(Array(5).keys()) is an ES6 alternative that works in typescript without the downlevelIteration compiler flag if anyone was looking
  • mwag
    mwag over 6 years
    @RafaelXavier will work on IE with Array.fill() polyfill
  • daveharris
    daveharris over 6 years
    This doesn't work when step != 1, the while condition needs to take step into account. My updated version with a default step value: function range(start, stop, step){ step = step || 1 var a=[start], b=start; while((b+step) < stop){ console.log("b: " + b + ". a: " + a + "."); b+=step; a.push(b); } return a; }
  • teashark
    teashark over 6 years
    In case this helps anyone: a range with low and high bounds: Array.apply(null, Array(bounds.high-bounds.low+1)).map(function (_, i) {return i+bounds.low;});
  • Doug
    Doug over 6 years
    For the love of everything holy, please don't mess with Object.prototype. It causes more pain than it's worth.
  • mikebridge
    mikebridge over 6 years
    Some android devices (mainly Samsung) seem to be missing Array.from: Uncaught TypeError: Object function Array() { [native code] } has no method 'from'.
  • 7vujy0f0hy
    7vujy0f0hy over 6 years
    @nafg: const range = (a, b, Δ = 1) => (a > b) ? [] : [a, ...range(a + Δ, b, Δ)];. Also upvoting the whole answer for the comment.
  • rodfersou
    rodfersou about 6 years
    let range = (start, stop, step=1) => Array(stop - start).fill(start).map((x, y) => x + y * step)
  • James Robey
    James Robey about 6 years
    This is actually wrong because the question is asking for start & end values. Not start & count/distance.
  • Paul
    Paul about 6 years
    I think there are off-by-one errors in these functions. Should be Array(end - start + 1), and Array(end.charCodeAt(0) - start.charCodeAt(0) + 1).
  • Mr. Polywhirl
    Mr. Polywhirl almost 6 years
    @daveharris I added a default step above, (step || 1).
  • user3167101
    user3167101 almost 6 years
    slice() does not modify the original array. Maybe you're thinking of splice().
  • rosenfeld
    rosenfeld almost 6 years
    Your longer version is actually shorter if you remove the unneeded "new" before Array.
  • Dana Woodman
    Dana Woodman almost 6 years
    While I'm sure a perfectly good answer in 2010, this should no longer be considered the best approach. You should not extend built in types, like Prototype.js tended to do 👍
  • Mike Dinescu
    Mike Dinescu almost 6 years
    @DanaWoodman thanks for bringing this up - I've updated the answer to take out the reference to Prototype.js since that is indeed pretty much obsolete in 2018
  • F Lekschas
    F Lekschas almost 6 years
    @rodfersou FYI: your example is wrong. stop is not actually the stop / end position but count / distance. (no offense, just to make people aware of the typo)
  • eedrah
    eedrah over 5 years
    For the confused - due to rodfersou's edit after F Lekschas' comment, his code is now correct.
  • Johan Dettmar
    Johan Dettmar over 5 years
    The argument you pass into Array(Math.ceil((stop - start) / step) + 1), needs the +1 at the end, to really mimic php's "inclusive" behaviour.
  • icc97
    icc97 over 5 years
    @StuCox I like your comment but fill requires at least one parameter, I guess you could just specify fill(undefined)
  • icc97
    icc97 over 5 years
    This is the top answer that actually answers the full question of a Javascript function that fully implements a range method. All the others currently above this (except for lodash's _.range) implement basic iterators rather than an actual range function with start, stop and step
  • Stu Cox
    Stu Cox over 5 years
    @icc97 Yes, linters may complain, although in JavaScript omitting a function argument defined to be the same as passing undefined, so fill() (with no argument) isn’t wrong per se. The fill value isn’t used in that solution, so if you like you could use fill(0) to save a few characters.
  • Stephen DuMont
    Stephen DuMont over 5 years
    Try this: Array(10).fill(1).map((x, i) => i)
  • Oleh Berehovskyi
    Oleh Berehovskyi about 5 years
    What does underscore '_' symbol represents in this case?
  • Soldeplata Saketos
    Soldeplata Saketos about 5 years
    you don't need the new keyword
  • Micah Zoltu
    Micah Zoltu about 5 years
    @OlehBerehovskyi It means a lambda function parameter that you have no intent of actually using. A linter that warns about unused variables should ignore it.
  • Pithikos
    Pithikos about 5 years
    Well this didn't help at all.
  • Mike Dinescu
    Mike Dinescu about 5 years
    @Pithikos I see this question has been edited since it was originally asked and the OP wanted to know if there is a native range function in JS.
  • cezar
    cezar almost 5 years
    Thank you so much. I use D3 and was looking for a native JS method, not knowing that I D3 offers it already.
  • miike3459
    miike3459 over 4 years
    You really shouldn't jerry-rig methods onto the Array prototype.
  • ximo
    ximo over 4 years
    I fixed @rodfersou's code so that stop means the end position: let range = (start, stop, step=1) => Array(stop - start + 1).fill(start).map((x, y) => x + y * step)
  • Victor
    Victor over 4 years
    This method only works with integers and characters. If the parameters are null, undefined, NaN, boolean, array, object, etc, this method returns the following error: undefined method toUpperCase to etc!
  • Victor
    Victor over 4 years
    ``` if (typeof from !== 'number' && typeof from !== 'string') { throw new TypeError('The first parameter should be a number or a character') } if (typeof to !== 'number' && typeof to !== 'string') { throw new TypeError('The first parameter should be a number or a character') } ```
  • Jon Koops
    Jon Koops over 4 years
    It's unwise to modify any built-in objects such as Array
  • Victor
    Victor about 4 years
    @JonKoops Can you explain why?
  • Jon Koops
    Jon Koops about 4 years
  • kaiser
    kaiser about 4 years
    quite smart solution with .fromCharCode().
  • Victor
    Victor about 4 years
    Good, I was aware of these details on the text you send, that's why I didn't modify the built-in objects in a normal way. I handled the Possible Conflicts scenario inside the algorithmn. You can notice I was aware of this on the "else" statement, which explicit let the user know that the Array.range function was already declared before. I also explained the possible side effects that may happen on this scenario! Therefore, I was aware of all the points mentioned on this text and that's why I created this wiser Pollyfill. So please don't lower the score on that without analyzing it properly.
  • Jon Koops
    Jon Koops about 4 years
    I understand, however that is still not an ideal solution. If any browser vendor ever implements this API this code will simply stop working.
  • Victor
    Victor about 4 years
    @JonKoops This code will not simply stop working, it is quite the opposite: it will let the developer know as soon as it will stop working. We can even use a report on the Sentry on the test environment (for example) as soon as it stop working in order to instantly inform this issue to the developer and prevent bugs. And if it stop working, the solution is very simple as fast, it is only required to change the name of the function and replace it to let it work again.
  • Jon Koops
    Jon Koops about 4 years
    Right, but the fact remains that an app running in production could suddenly stop operating as intended. I'm sorry, but adding tooling still isn't going to fix the original problem.
  • Saravanabalagi Ramachandran
    Saravanabalagi Ramachandran about 4 years
    jsPerf for Array from, Array fill and Array spread. Array fill is the fastest as mentioned by @StuCox
  • lokhmakov
    lokhmakov about 4 years
    Just const range = (x, y) => Array.from(function* () { while (x <= y) yield x++; }())
  • Hero Qu
    Hero Qu about 4 years
    @lokhmakov Yes, you are right. thank you! Just applied your code in my answer.
  • ysf
    ysf almost 4 years
    While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation.
  • ion
    ion almost 4 years
    Additional check for typeof from === typeof to
  • Mukesh Chapagain
    Mukesh Chapagain over 3 years
    Just in case, if you want to start the array with 1, then you can do so by passing map function to Array from() Array.from(Array(10), (_, i) => i + 1) //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Source: stackoverflow.com/a/33352604/327862
  • Michael Durrant
    Michael Durrant over 3 years
    Start array size 'n' at whatever 'startAt' number you want by "slicing" off the first numbers using [...Array(n).keys()].slice(startAt-1), .e. [...Array(7).keys()].slice(4) for [4,5,6,7]
  • mastazi
    mastazi over 3 years
    Instead of for (const x of Array(5).keys()) just do for (const x in Array(5)) since for... in... iterates over the keys.
  • Fuji
    Fuji over 3 years
    @mastazi Array(5) != [0, 1, 2, 3, 4]. The Array function generates an empty array. The key() method is required to populate the iterator
  • Admin
    Admin over 3 years
    Too long. Most of the solutions presented are extremely short and elegant.
  • Lewis Morris
    Lewis Morris over 3 years
    Pretty comprehensive i'd say
  • windmaomao
    windmaomao over 3 years
    i have to say just by looking at it, if you try million records, it'll crash your computer. If not, just try with one more zero. I don't think you can exceed a number with more than 8 zeros.
  • Mads Buch
    Mads Buch about 3 years
    This one should be considered the answer with preference on the iterable solution. Especially for large ranges this approach is faster and saves space.
  • Simon Zyx
    Simon Zyx about 3 years
    maybe better [...Array(end-start+1)].map((el, ind) => ind + start); ?
  • argon
    argon about 3 years
    @rodfersou - you're a legend!
  • Cezar D.
    Cezar D. almost 3 years
    Indeed Array(5).fill() is mappable, and preferable because is WAY more performant (~4x) than the spread of [...Array(5).keys()]
  • ElectRocnic
    ElectRocnic almost 3 years
    This answer does not work as expected. The output is not usable.
  • Chris Schaller
    Chris Schaller over 2 years
    For such an old post, you need to include some commentary on why your answer is superior to the other 69 answers on this topic. Code-Only is simply not acceptable for posts like these, how is any user supposed to pick yours out of all that?
  • Dazzle
    Dazzle over 2 years
    It's 2021 and this thread is full of totally overcomplicated ways of achieving this basic operation. Some users like me would like to see something easy to understand. Updated my code to give context to vue users
  • iva2k
    iva2k over 2 years
    All - Please read this and upvote. It should be the top answer by far.
  • MEMark
    MEMark over 2 years
    OP doesn't even say anything about using Vue.
  • Dazzle
    Dazzle over 2 years
    Welcome to 2021
  • aloisdg
    aloisdg over 2 years
    If you have a downlevelIteration warning, see this answer
  • Princewill Ezeidei
    Princewill Ezeidei over 2 years
    This was exactly what I needed. the step option. Thanks.
  • Robert Monfera
    Robert Monfera over 2 years
    The Array.from form could eventually be faster than spread etc. for the original use case on the top (while the spreading version of the answer here doesn't generate what the OP asked). The reason for why Array.from could be faster is that the spec doesn't require the materialization of an interim array with undefineds, as the callback function (2nd arg of Array.from) can directly run as the initial array is being written. Faster, and lower pressure on GC if browsers optimize this as the spec expressly hints at it
  • Neurotransmitter
    Neurotransmitter over 2 years
    Works in TS nicely.
  • Stevers
    Stevers over 2 years
    Good lord what a great answer. THank you for this good person.
  • General Grievance
    General Grievance over 2 years
    There are a lot of other answers here. What makes this different from the rest?
  • row
    row over 2 years
    As miike3459 wrote, if one day Array.range is added to standard lib you might have a serious problem.
  • Bergi
    Bergi over 2 years
    Interesting way of making the iterator object reusable :)
  • CrackerKSR
    CrackerKSR over 2 years
    @Bergi Thanks :)
  • Jacktose
    Jacktose about 2 years
    FYI MDN recommends a range function like the second example here: const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
  • Michael Plautz
    Michael Plautz about 2 years
    A slightly less greedy yet still concise alternative, Array(1 + upper - lower).fill().map((v, i) => i + lower)
  • hariseldon78
    hariseldon78 about 2 years
    the external brackets can be removed safely: ` [...Array(10-3).keys()].map(i=>i+3) == [ 3, 4, 5, 6, 7, 8, 9 ] `
  • qba-dev
    qba-dev about 2 years
    it would work as expected, when Array(end - 1) is changed like Array(end - start + 1)