# Array.create

**URL:** <https://es.discourse.group/t/array-create/628>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [February 2, 2021, 7:58am UTC](https://es.discourse.group/t/array-create/628 "2021-02-02T07:58:14Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![aaditmshah](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aaditmshah/32/602_2.png) [@aaditmshah](https://es.discourse.group/u/aaditmshah)\
**Post date:** [February 2, 2021, 7:58am UTC](https://es.discourse.group/t/array-create/628/1 "2021-02-02T07:58:14Z")

</div>

# Abstract

JavaScript doesn't have a canonical function to create an array. This is a pity, because it discourages developers from adopting a functional style of programming. I propose that we add an `Array.create` function to the language. This will lead to cleaner code and the building of better abstractions.

# Background

Traditionally, creation of arrays in JavaScript was done using procedural code. Then, with ES6 we got the `Array.from` function which made it easier to create arrays in a functional style. However, the canonical purpose of `Array.from` is converting iterables into arrays. Therefore, using it to create arrays is wonky.

```
// Array.create :: (Int, Int -> a) -> Array a
Array.create = (length, mapping) =>
    Array.from({ length }, (value, index) => mapping(index));

```

It would be nicer to have a canonical function to create arrays, such as the `Array.create` function shown above. Due to a lack of such a canonical function, we currently have packages such as [`create-array`](https://www.npmjs.com/package/create-array) in the NPM ecosystem. This leads to package bloat and possible code duplication as developers reinvent the wheel in every new project.

# Motivation

Another reason to include the `Array.create` function would be to encourage developers to build better abstractions. For example, we can use `Array.create` to [create and transpose matrices](https://stackoverflow.com/a/66004866/783743) easily.

```
class Matrix {
    // new Matrix :: (Int, Int, Array (Array a)) -> Matrix a
    constructor(rows, cols, data) {
        this.rows = rows;
        this.cols = cols;
        this.data = data;
    }

    // Matrix.create :: (Int, Int, (Int, Int) -> a) -> Matrix a
    static create(rows, cols, mapping) {
        const data = Array.create(rows, row =>
            Array.create(cols, col => mapping(row, col)));
        return new Matrix(rows, cols, data);
    }

    // Matrix#transpose :: Matrix a ~> () -> Matrix a
    transpose() {
        const { rows, cols, data } = this;
        return Matrix.create(cols, rows, (row, col) => data[col][row]);
    }
}

```

# Conclusion

The `Array.create` function is very useful. It encourages a functional style of programming, we can use it to build better abstractions, and it would prevent developers from reinventing the wheel in every project.

---

<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:** [February 3, 2021, 8:51pm UTC](https://es.discourse.group/t/array-create/628/2 "2021-02-03T20:51:25Z")

</div>

Alternative iterator based proposals: [GitHub - tc39/proposal-Number.range: A proposal for ECMAScript to add a built-in Number.range()](https://github.com/tc39/proposal-Number.range) and [GitHub - tc39/proposal-iterator-helpers: Methods for working with iterators in ECMAScript](https://github.com/tc39/proposal-iterator-helpers) would also allow this.

They could also be used to implement `Array.create`

```javascript
Array.create = (length, mapping) =>
    [...Number.range(0, length).map(mapping)]

```

---

<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:** [February 3, 2021, 10:16pm UTC](https://es.discourse.group/t/array-create/628/3 "2021-02-03T22:16:24Z")

</div>

there’s also the old pre-ES6 proposal [http://array.build](http://array.build)

---

<div class="post-metadata">

**Author:** ![aaditmshah](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aaditmshah/32/602_2.png) [@aaditmshah](https://es.discourse.group/u/aaditmshah)\
**Post date:** [February 4, 2021, 4:33am UTC](https://es.discourse.group/t/array-create/628/4 "2021-02-04T04:33:04Z")

</div>

@aclaymore I would argue that it still makes sense to add `Array.create` (or `Array.build` as @ljharb shared) to the language for the following reasons.

1. It's such a primitive operation that it warrants a language level implementation. There's no reason why we can't have both `Array.create` and `Number.range` in the language.
2. By adding `Array.create` to the language, we won't require 3rd party packages like [`create-array`](https://github.com/JsCommunity/create-array) and we won't have to keep reinventing the wheel in every project.
3. By adding `Array.create` to the language, more developers will become aware of it and use it in their programs. Hence, it will promote a functional style of programming.
4. Implementing `Array.create` in the user space (whether using `Array.from` or `Number.range`) doesn't address any of the above issues.

The motivation for adding `Array.create` to the language is the same as the motivation for adding `Number.range` to the language, [as stated by the proposal that you shared](https://github.com/tc39/proposal-Number.range#motivation).

> - because we don't have it yet™

Both `Array.create` and `Number.range` are primitive operations that can be implemented in the user space, but should be provided by the language itself.

---

<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:** [February 15, 2021, 5:32pm UTC](https://es.discourse.group/t/array-create/628/5 "2021-02-15T17:32:58Z")

</div>

There's an advantage to using your method, though: engines can pre-allocate the full length in one go, making it slightly faster.

---

<div class="post-metadata">

**Author:** ![aaditmshah](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aaditmshah/32/602_2.png) [@aaditmshah](https://es.discourse.group/u/aaditmshah)\
**Post date:** [June 2, 2021, 6:27am UTC](https://es.discourse.group/t/array-create/628/6 "2021-06-02T06:27:09Z")

</div>

Please may we get this function added to the language?

---

<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:** [October 25, 2021, 8:40pm UTC](https://es.discourse.group/t/array-create/628/7 "2021-10-25T20:40:57Z")

</div>

Linking duplicate threads: [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)
