Question

How to Create an Array from 1 to N in JavaScript

javascriptarraysrange

Question

I want to create a JavaScript array containing the numbers 1 through N, where N is only known at runtime.

One approach is to use a loop like this:

var foo = [];

for (var i = 1; i <= N; i++) {
  foo.push(i);
}

Are there alternative ways to build this array, especially using a more declarative style instead of manually pushing values in a loop?

Short Answer

By the end of this page, you will understand how to generate a sequence like 1...N in JavaScript, why loops are still valid, and how built-in tools such as Array.from() can make this pattern shorter and clearer.

Concept

In JavaScript, creating an array of numbers from 1 to N is really about generating a numeric range.

A range is a sequence of values that follow a pattern:

  • 1, 2, 3, 4, 5
  • 0, 1, 2, 3, 4
  • 10, 20, 30

JavaScript does not have a built-in range literal like some other languages. That means you usually create ranges using:

  • a for loop
  • Array.from()
  • array keys and mapping
  • a reusable helper function

Your original loop is completely valid. In fact, it is often the clearest solution for beginners. But modern JavaScript provides more expressive options when you want to describe the result rather than manually build it step by step.

This matters in real programming because generating ranges is common when:

  • paginating results
  • building dropdowns such as years or days
  • creating test data
  • repeating operations a fixed number of times
  • indexing rows, columns, or steps

So the real concept is not just “avoiding a loop.” It is learning how JavaScript constructs arrays from patterns.

Mental Model

Think of this like filling numbered tickets into a box.

  • A for loop means: “Start at ticket 1, keep adding the next ticket until you reach N.”
  • Array.from() means: “Give me a box with N slots, and for each slot, compute the value that should go there.”

Both approaches still do repeated work internally. The difference is mostly how you express your intent:

  • loop: how to build it
  • declarative method: what array you want

So even when you “avoid the loop,” JavaScript is still iterating somewhere under the hood.

Take Quiz

Syntax and Examples

A modern and common way to create an array from 1 to N is with Array.from().

const N = 5;
const numbers = Array.from({ length: N }, (_, index) => index + 1);

console.log(numbers); // [1, 2, 3, 4, 5]

How this works

  • { length: N } creates an array-like object with N slots.
  • Array.from() turns it into a real array.
  • The callback runs once for each position.
  • index starts at 0, so we add 1 to get 1...N.

Traditional loop version

const numbers = [];
for (let i = 1; i <= N; i++) {
  numbers.push(i);
}

This is still correct and easy to read.

Starting from 0 instead

const numbers = Array.from({ length: N }, (_, index) => index);

console.log(numbers); // [0, 1, 2, 3, 4] if N = 5

Reusable helper function

function rangeOneToN(n) {
  return Array.from({ length: n }, (_, index) => index + 1);
}

console.log(rangeOneToN(7)); // [1, 2, 3, 4, 5, 6, 7]

This is useful when you need the same pattern in multiple places.

Step by Step Execution

Consider this code:

const N = 4;
const result = Array.from({ length: N }, (_, index) => index + 1);
console.log(result);

Step by step

  1. N is set to 4.
  2. { length: N } becomes { length: 4 }.
  3. Array.from() prepares to create an array with 4 items.
  4. The callback runs once for each index:
    • index 0 → 0 + 1 → 1
    • index 1 → 1 + 1 → 2
    • index 2 → 2 + 1 → 3
    • index 3 → 3 + 1 → 4
  5. The final array becomes:
[1, 2, 3, 4]

Equivalent loop trace

const result = [];
for (let i = 1; i <= 4; i++) {
  result.push(i);
}
  • Start with []
  • Push 1 → [1]
  • Push 2 → [1, 2]
  • Push 3 → [1, 2, 3]
  • Push 4 → [1, 2, 3, 4]

Both versions produce the same result.

Real World Use Cases

Generating arrays from 1 to N appears in many practical situations.

Pagination

const totalPages = 5;
const pages = Array.from({ length: totalPages }, (_, i) => i + 1);
// [1, 2, 3, 4, 5]

Use this to render page buttons in a UI.

Year dropdowns

const numberOfYears = 10;
const years = Array.from({ length: numberOfYears }, (_, i) => 2020 + i);

Useful for forms and filters.

Generating placeholder rows

const skeletonRows = Array.from({ length: 3 }, (_, i) => ({ id: i + 1, loading: true }));

Common in front-end apps while data is loading.

Running a task N times

Array.from({ length: 5 }, (_, i) => `Task ${i + 1}`);

Useful for labels, test data, or batch operations.

Take Quiz

Real Codebase Usage

In real projects, developers often wrap range generation inside helper functions so the intent is clear.

Common helper pattern

function range(start, end) {
  return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}

console.log(range(1, 5)); // [1, 2, 3, 4, 5]

This is more reusable than hardcoding 1...N every time.

Guard clause for invalid input

function rangeOneToN(n) {
  if (!Number.isInteger(n) || n < 1) {
    return [];
  }

  return Array.from({ length: n }, (_, i) => i + 1);
}

This avoids bugs when n is negative, not a number, or not an integer.

Used with mapping and rendering

const buttons = Array.from({ length: 3 }, (_, i) => ({
  label: `Step ${i + 1}`,
  value: i + 1
}));

Developers often generate numeric ranges not for the numbers themselves, but to create structured objects for UI, configuration, or processing.

Early validation pattern

Before building a range, real code often checks:

  • Is n defined?
  • Is n a positive integer?
  • Is the range too large?

That keeps utility functions safe and predictable.

Common Mistakes

Here are common mistakes beginners make when creating a range.

Off-by-one errors

Broken code:

const numbers = Array.from({ length: 5 }, (_, i) => i);
console.log(numbers); // [0, 1, 2, 3, 4]

If you want 1...N, add 1:

const numbers = Array.from({ length: 5 }, (_, i) => i + 1);

Using new Array(N).map(...)

Broken code:

const numbers = new Array(5).map((_, i) => i + 1);
console.log(numbers); // unexpected result

This does not work as many beginners expect because the array contains empty slots, and map() skips them.

Use this instead:

const numbers = Array.from({ length: 5 }, (_, i) => i + 1);

Forgetting invalid input

Broken code:

function rangeOneToN(n) {
  return Array.from({ length: n }, (_, i) => i + 1);
}

If n is negative or not an integer, the result may not be what you want.

Safer version:

function rangeOneToN(n) {
  if (!Number.isInteger(n) || n < 1) return [];
  return Array.from({ length: n }, (_, i) => i + 1);
}

Assuming declarative code means no iteration

Even with Array.from(), iteration still happens internally. The benefit is cleaner expression, not elimination of repeated work.

Using var unnecessarily

Older code often uses var, but modern JavaScript usually prefers:

  • const for values that do not get reassigned
  • let for loop counters or changing values

Comparisons

Here is a comparison of common ways to create a range in JavaScript.

ApproachExampleBest forNotes
for loopfor (let i = 1; i <= n; i++)Beginners, explicit logicVery clear and efficient
Array.from()Array.from({ length: n }, (_, i) => i + 1)Clean modern codeVery common and readable
new Array(n).fill().map()new Array(n).fill(0).map((_, i) => i + 1)When you want to use map()Works, but more verbose
Helper functionrange(1, n)Reuse across a projectBest when range logic appears often

for loop vs Array.from()

Featurefor loopArray.from()
ReadabilityVery explicitMore declarative
Beginner-friendlyYesYes, after learning callback syntax
ReusabilityManual unless wrappedEasy to wrap in a function
ControlFull controlGreat for straightforward patterns

There is no single “correct” answer. In many codebases, both styles are acceptable.

Take Quiz

Cheat Sheet

Create 1...N

const arr = Array.from({ length: N }, (_, i) => i + 1);

Create 0...(N-1)

const arr = Array.from({ length: N }, (_, i) => i);

Loop version

const arr = [];
for (let i = 1; i <= N; i++) {
  arr.push(i);
}

Reusable helper

function rangeOneToN(n) {
  if (!Number.isInteger(n) || n < 1) return [];
  return Array.from({ length: n }, (_, i) => i + 1);
}

Important rules

  • Array.from({ length: N }, callback) runs the callback N times.
  • Indexes start at 0.
  • Use i + 1 to get 1...N.
  • new Array(N).map(...) does not behave as expected with empty slots.
  • A loop is not bad practice here; it is often perfectly clear.

Edge cases

  • N = 0 → []
  • negative N → validate first
  • non-integer N → usually reject or normalize intentionally

FAQ

Is a for loop bad for creating an array from 1 to N?

No. A for loop is a clear and efficient solution. Modern alternatives are mainly about readability and style.

What is the shortest modern JavaScript way to create 1...N?

Array.from({ length: N }, (_, i) => i + 1)

Why does new Array(N).map(...) not work properly?

Because new Array(N) creates empty slots, and map() skips them. Use Array.from() or .fill() first.

Can I create a reusable range function in JavaScript?

Yes:

function range(start, end) {
  return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}

What happens if N is 0?

You get an empty array:

Array.from({ length: 0 }, (_, i) => i + 1); // []

Should I use var, let, or const here?

Use const for the final array reference and let for a loop counter if needed. Avoid var in modern JavaScript unless you specifically need its older function-scoped behavior.

Is there really a way to do this without a loop?

Not truly. Some kind of iteration still happens. Methods like Array.from() just hide the loop behind a cleaner interface.

Take Quiz

Mini Project

Description

Build a small utility that generates page numbers for a pagination component. This demonstrates how to create an array from 1 to N in a practical way, while also validating input so the function behaves safely.

Goal

Create a function that returns an array of page numbers from 1 to a given total page count.

Requirements

  • Write a function named createPageNumbers.
  • Return an empty array if the input is not a positive integer.
  • Return page numbers starting at 1 and ending at N.
  • Test the function with valid and invalid inputs.
Take Quiz

Keep learning

Related questions

View more