Home  >  Article  >  Web Front-end  >  Introduction to methods of creating and filling arrays of arbitrary length in JavaScript (with code)

Introduction to methods of creating and filling arrays of arbitrary length in JavaScript (with code)

不言
不言forward
2019-02-25 10:18:5314127browse

This article brings you an introduction to the method of creating and filling arrays of any length in JavaScript (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

The best way to create an array is through literal means:

const arr = [0,0,0];

But this is not a long-term solution, such as when we need to create a large array. This blog post explores what to do in this situation.

Arrays without holes tend to perform better

In most programming languages, an array is a continuous sequence of values. In JavaScript, an Array is a dictionary that maps indices to elements. It can have holes - indexes between zero and the length of the array that are not mapped to elements ("missing indexes"). For example, the following Array has a hole at index 1:

> Object.keys(['a',, 'c'])
[ '0', '2' ]

An array without holes is also called dense or packed. Dense arrays tend to perform better because they can be stored contiguously (internally). Once a hole occurs, the internal representation must change. We have two options:

  • Dictionary. The search will take more time and the storage overhead will be greater.

  • Continuous data structure to mark holes. Then check whether the corresponding value is a hole, which also requires additional time.

In either case, if the engine encounters a hole, it can't just return undefined, it must traverse the prototype chain and search for a hole index named ” properties, which takes more time.

In some engines, such as V8, if you switch to a less performant data structure, the change will be permanent. Even if all the holes are filled, they won't switch back again.

For more information on how V8 represents arrays, see Mathias Bynens' article "Element Types in V8".

Create Array

Array Constructor

If you want to create an Array with a given length, the common method is to use ArrayConstructor:

const LEN = 3;
const arr = new Array(LEN);
assert.equal(arr.length, LEN);
// arr only has holes in it
assert.deepEqual(Object.keys(arr), []);

This method is very convenient, but it has two disadvantages:

  • Even if you completely fill the array with values ​​later, this method Holes will also make this Array slightly slower.

  • The default value of a hole is generally not the initial "value" of the element. A common default value is zero.

Add .fill() method

.fill()# after the

Array constructor ##Method will change the current Array and fill it with the specified value. This helps in initializing an array after creating it with new Array():

const LEN = 3;
const arr = new Array(LEN).fill(0);
assert.deepEqual(arr, [0, 0, 0]);

Warning: If you use an object as a parameter to . fill() An array, all elements will refer to the same instance (that is, this object has not been cloned multiple times):

const LEN = 3;
const obj = {};

const arr = new Array(LEN).fill(obj);
assert.deepEqual(arr, [{}, {}, {}]);

obj.prop = true;
assert.deepEqual(arr,
  [ {prop:true}, {prop:true}, {prop:true} ]);
A filling method we will encounter later (

Array.from()) does not have this problem.

.push() Method
const LEN = 3;
const arr = [];
for (let i=0; i < LEN; i++) {
  arr.push(0);
}
assert.deepEqual(arr, [0, 0, 0]);

This time, we created and filled an array without any holes in it. So manipulating this array should be faster than creating it using the constructor. However

Creating arrays is slower because the engine may need to reallocate contiguous memory multiple times as the array grows.

Fill an array with

undefined

Array.from() Convert iterables and array-like values ​​to Arrays, which treats holes as undefined element. In this way, you can use it to convert each hole into undefined:

> Array.from({length: 3})
[ undefined, undefined, undefined ]
Parameter

{length: 3} is an Array-like object with a length of 3, where Contains nothing but holes. You can also use new Array(3), but this will generally create a larger object. The following method only applies to iterable values, and has a similar effect to
Array.from():

> [...new Array(3)]
[ undefined, undefined, undefined ]
But

Array.from()Create its result via new Array() so what you get is still a sparse array.

Use

Array.from() for mapping

If you provide a mapping function as its second parameter, you can use

Array.from() Perform mapping.

Fill the array with values

  • Create an array using small integers:

    > Array.from({length: 3}, () => 0)
    [ 0, 0, 0 ]
  • Create using a unique (non-shared) object Array:

    > Array.from({length: 3}, () => ({}))
    [ {}, {}, {} ]
Create according to the numerical range

  • Create an array using an ascending integer sequence:

    > Array.from({length: 3}, (x, i) => i)
    [ 0, 1, 2 ]
  • Create with any range of integers:

    > const START=2, END=5;
    > Array.from({length: END-START}, (x, i) => i+START)
    [ 2, 3, 4 ]
Another way to create an ascending array of integers is to use

.keys(), which will also look empty The operation is undefined Elements:

> [...new Array(3).keys()]
[ 0, 1, 2 ]

.keys()Returns an iterable sequence. We expand it and convert it to an array.

Quick Memo: Create an Array

Fill it with holes or

undefined:

  • new Array(3 )
    [ , , ,]

  • Array.from({length: 2})
    [undefined, undefined]

  • [...new Array(2)]
    [undefined, undefined]

填充任意值:

  • const a=[]; for (let i=0; i<3; i++) a.push(0);
    [0, 0, 0]

  • new Array(3).fill(0)
    [0, 0, 0]

  • Array.from({length: 3}, () => ({}))
    [{}, {}, {}] (唯一对象)

用整数范围填充:

  • Array.from({length: 3}, (x, i) => i)
    [0, 1, 2]

  • const START=2, END=5; Array.from({length: END-START}, (x, i) => i+START)
    [2, 3, 4]

  • [...new Array(3).keys()]
    [0, 1, 2]

推荐的模式

我更喜欢下面的方法。我的侧重点是可读性,而不是性能。

  • 你是否需要创建一个空的数组,以后将会完全填充?

    new Array(LEN)
  • 你需要创建一个用原始值初始化的数组吗?

    new Array(LEN).fill(0)
  • 你需要创建一个用对象初始化的数组吗?

    Array.from({length: LEN}, () => ({}))
  • 你需要创建一系列整数吗?

    Array.from({length: END-START}, (x, i) => i+START)

如果你正在处理整数或浮点数的数组,请考虑Typed Arrays —— 它就是为这个目的而设计的。它们不能存在空洞,并且总是用零进行初始化。

提示:一般来说数组的性能无关紧要

  • 对于大多数情况,我不会过分担心性能。即使是带空洞的数组也很快。使代码易于理解更有意义。

  • 另外引擎优化的方式和位置也会发生变化。今天最快的方案可能明天就不是了。

The above is the detailed content of Introduction to methods of creating and filling arrays of arbitrary length in JavaScript (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete