# Ranges and Generating Arrays in JavaScript

**URL:** <https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589>\
**Category:** I have questions\
**Created:** [January 14, 2023, 2:31pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589 "2023-01-14T14:31:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 14, 2023, 2:31pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/1 "2023-01-14T14:31:01Z")

</div>

Have any of you found cool ways of generating arrays in js. I don't have to do this very often, but this is the best way I've found to do it.

```javascript
const firstTenSqaures = Array.from(Array(10), (_, i) => i ** 2)

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [January 14, 2023, 4:09pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/2 "2023-01-14T16:09:04Z")

</div>

I’d suggest avoiding the Array constructor entirely - use `{ length: 10 }` instead of Array(10).

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 14, 2023, 4:23pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/3 "2023-01-14T16:23:12Z")

</div>

Yeah, I know you can do that `{ length: 10 }`, but that kind of looks like magic. Why should the Array constructor be avoided?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [January 14, 2023, 4:33pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/4 "2023-01-14T16:33:33Z")

</div>

Because it creates a sparse array.

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 14, 2023, 5:38pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/5 "2023-01-14T17:38:32Z")

</div>

Right. I didn't think that would really matter here. What about?

```javascript
const tenTens = new Array(10).fill(10)

```

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [January 14, 2023, 7:35pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/6 "2023-01-14T19:35:25Z")

</div>

I'm not sure what qualifies as cool but generators provide a lot of fun!

```javascript
Array.from((function*() {
  for (let i = 0; i < 10; i++) yield i ** 2;
})()); // [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

```

---

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [January 15, 2023, 1:32am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/7 "2023-01-15T01:32:49Z")

</div>

There's also a range proposal: [Iterator.range()](https://github.com/tc39/proposal-Number.range)

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 15, 2023, 3:41am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/8 "2023-01-15T03:41:42Z")

</div>

That would also be good. I feel like the question could also be phrased, what's the least ugly way to do this in js 😂

---

<div class="post-metadata">

**Author:** ![graphemecluster](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/graphemecluster/32/957_2.png) [@graphemecluster](https://es.discourse.group/u/graphemecluster)\
**Post date:** [January 19, 2023, 1:00am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/9 "2023-01-19T01:00:37Z")

</div>

Please refer to the active thread:

> [@Provide an easy way to create a new array, filled via a mapping function](https://es.discourse.group/t/provide-an-easy-way-to-create-a-new-array-filled-via-a-mapping-function/1056/57):
>
> I "gathered some data" (actually, it was just personal experience) related to this. Look at [this commit history](https://github.com/bjpop/js-turtle/commits/cddcf39206735bb0f974a5fc9a093388467ff2d1/examples/bounce.js). As you can see, we started with Array(n)+for loop (probably because in "the old days" pre-allocating an array was faster than repeatedly pushing values, otherwise the garbage-collector and the allocator would work too much). Then we transitioned to []+while (n--)+push. Then Array(n).fill().map(). And finally Array.from({ length }, ...). I was confused as to why this is a "hacky sol…

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [January 19, 2023, 6:51am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/10 "2023-01-19T06:51:10Z")

</div>

That just returns `[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]`. If you're looking for a range, `Array.prototype.fill` is probably not what you're looking for.

[~~Now if only we could get implementors to optimize it correctly.~~](https://crbug.com/v8/6892)

---

<div class="post-metadata">

**Author:** ![Benimation](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/benimation/32/1220_2.png) [@Benimation](https://es.discourse.group/u/Benimation)\
**Post date:** [January 19, 2023, 11:14am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/11 "2023-01-19T11:14:17Z")

</div>

I usually do something like:

```javascript
const myRange = [...new Array(33)]
  .map((item, index) => index + 10);

```

But we really need a standard range functionality

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 19, 2023, 9:00pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/12 "2023-01-19T21:00:41Z")

</div>

Right, I was just pointing this out as maybe an acceptable case to use the array constructor.

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [January 19, 2023, 9:04pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/13 "2023-01-19T21:04:46Z")

</div>

That's kind of esoteric knowledge that `{length: n}` works as an array under the hood, imo. Or is an "arrayLike" I guess.

---

<div class="post-metadata">

**Author:** ![ogbotemi-2000](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ogbotemi-2000/32/1634_2.png) [@ogbotemi-2000](https://es.discourse.group/u/ogbotemi-2000)\
**Post date:** [February 4, 2023, 1:02pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/14 "2023-02-04T13:02:31Z")

</div>

> The problem of unintuitive code in generating arrays in JavaScript can be solved as follows:

- Knowing the 'Number' (an unobvious pun) of array items needed.
- Generating the array using a getter defined on the 'Number';

```javascript

/* x is used as a variable below in order to bring in a sense of multiplication by some value to give
 * an array, in this case, as a result
*/
const x = Symbol ? Symbol() : '1bda4e5b-9819-49f0-bcb3-946697b3b663';
//Symbol() does not return a string as its unique id

//x is defined on the Number.prototype object as a getter
Object.defineProperty(Number.prototype, x, {
  get() {
    /* this.valueOf below return the number that is currently accessing x as a property
     */
    let arg=[], n=this.valueOf(), i=0;
    for(; i++<n; arg[i-1]=i-1); return arg;
  },
}); 

/*syntaxes such as 5.x, 10.x won't work because the JavaScript compiler cannot be sure whether
  * the dot is for a floating point number or for object property accession.
  * it is safe to use syntaxes such as 5[x], 10[x]
  */
5[x] // [0, 1, 2, 3, 4]
200[x] // [0, 1, ..., 199]

```

_Hopefully this helps someone, I look forward to corrections and code improvements_

---

<div class="post-metadata">

**Author:** ![Josh-Cena](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/josh-cena/32/1408_2.png) [@Josh-Cena](https://es.discourse.group/u/Josh-Cena)\
**Post date:** [February 4, 2023, 5:29pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/15 "2023-02-04T17:29:28Z")

</div>

> syntaxes such as 5.x, 10.x won't work because the JavaScript compiler cannot be sure whether the dot is for a floating point number or for object property accession.

To solve the syntax issue, you can write `5..x`, but the real issue is that this accesses the property called `x` instead of using the expression `x`.

Also, speaking of modifying prototypes, maybe someone would enjoy a proxy treat:

```javascript
Object.setPrototypeOf(
  Number.prototype,
  new Proxy(Object.prototype, {
    get(t, p, r) {
      if (typeof p === "string") {
        const np = Number(p);
        if (Number.isFinite(np)) {
          const n = Number(r);
          return (function* () {
            if (n < np) {
              for (let i = n; i < np; i++) {
                yield i;
              }
            } else {
              for (let i = n; i > np; i--) {
                yield i;
              }
            }
          })();
        }
      }
      return Reflect.get(t, p, r);
    },
  })
);

console.log([...10[-3]]);
console.log([...0[5]]);

```

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [February 5, 2023, 10:00pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/16 "2023-02-05T22:00:07Z")

</div>

That’s cool. `5..x` looks like a range, but it’s backwards in this case. `0..5`

Unfortunately `0..5` is not valid syntax. But I'm trying to think of some other way like `1..x=100`

---

<div class="post-metadata">

**Author:** ![Josh-Cena](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/josh-cena/32/1408_2.png) [@Josh-Cena](https://es.discourse.group/u/Josh-Cena)\
**Post date:** [February 5, 2023, 10:39pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/17 "2023-02-05T22:39:53Z")

</div>

`1..to10`, `1..to(10)`, and `1..to[10]` are all possible designs. The issue is that they all create string properties which could harm forward compatibility. Number properties are less dangerous in this regard.

---

<div class="post-metadata">

**Author:** ![Rudxain](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rudxain/32/2272_2.png) [@Rudxain](https://es.discourse.group/u/Rudxain)\
**Post date:** [April 13, 2023, 5:28am UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/18 "2023-04-13T05:28:01Z")

</div>

> `[...0[5]]`

I think that's the closest thing to operator-overloading in JS. I'm not sure if I should feel amazed or horrified, haha (No offense intended! That code is actually a very interesting proof-of-concept. I like it 👍)

---

<div class="post-metadata">

**Author:** ![seekr3](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/seekr3/32/476_2.png) [@seekr3](https://es.discourse.group/u/seekr3)\
**Post date:** [April 13, 2023, 2:47pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/19 "2023-04-13T14:47:37Z")

</div>

What's this supposed to do, I put this into the terminal and it spat out `caught TypeError: 0[5] is not iterable`

All these are pretty gross honestly, maybe just a range function would be the way to go 😂 `range(0, 5)`

Without installing any npm dependencies, I'm pretty happy with

```js
const firstTenSqaures = Array.from({ length: 10 }, (_, i) => i ** 2)

```

The times I actually need ranges in js is pretty seldom, but still an interesting topic.

---

<div class="post-metadata">

**Author:** ![Josh-Cena](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/josh-cena/32/1408_2.png) [@Josh-Cena](https://es.discourse.group/u/Josh-Cena)\
**Post date:** [April 13, 2023, 2:59pm UTC](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589/20 "2023-04-13T14:59:18Z")

</div>

@seekr3 Did you run the previous line, which basically hijacks `Number.prototype`?

[Next page](https://es.discourse.group/t/ranges-and-generating-arrays-in-javascript/1589.md?page=2)
