Table of content:
- Arrays Introduction
- How to create an Array in Javascript?
- How to access an Array item
- How to update an Array item
- Array length property
- typeof Array
- How to check if variable is an Array
- How to loop over Array items (forEach)
- How to add item to Array (push, unshift)
- How to remove item from Array (pop, shift)
- How to replace items in Array
- How to find item position in Array
- How to sort Array
- Array iteration methods (map, filter, reduce, find)
- How to reverse Array
- How to merge Arrays
- How to check if an item is present in Array
Advanced section:
- Spared arrays
- How to fill array with value
- How to create an Array from an arrays like objects
- How to remove all duplicates from an Array
Arrays Introduction
Arrays - it’s a composing data structure, that consist of ordered objects. In some programming languages, arrays have low-level optimization for these objects because of sequence storing them into the memory. In javascript, it a little bit confusing, because, in javascript, arrays are just objects with some special behavior, that allows emulating array interface. More about that in the typeof
section.
How to create an Array in Javascript?
There’re a few ways of creating arrays in javascript. Let’s start considering them here. The first one is by using array literal notation (empty brackets):
const a = []
Also, you can pass any object into the array:
const a = [1, 'foo', false]
Creating an array using Array constructor
is equal to defining array using literal notation:
const a = new Array() // []
And you can still pass any items into the constructor:
const a = new Array('foo', 'bar', 'baz') // ['foo', 'bar', 'baz']
But there’s an exception with a single number as an argument. In that case, will be created an array of the relative amount of empty items. Notice, that they are really empty slots and aren’t undefined
. It’s really a very important. And read more about that in the advanced section
:
const a = new Array(5) // [,,,,]
But in the other cases, it works as expected:
const a = new Array('foo') // ['foo']
ES6 added some more ways to create an Array
instance. Array.of
works the same as new Array
but without exception for single number as argument, so it totally equal to the literal notation:
const a = Array.of(5)
And the last possible way to create array - it’s using the Array.from
method, that allows converting array-like object’s (object with length
property) or any iterable item (string
, for example) to an array. More details about using this method in the advanced section.
const a = Array.from({ length: 2 })
How to access an Array item
Each Array
element has own index (of position), that starts from 0
. For getting some item you have to just use this index:
const a = ['foo', 'bar']
console.log(a[0]) // 'foo'
How to update an Array item
For updating or setting Array
item you have to also use an element index and plain assigning expression:
const a = ['foo', 'bar', 3] // ['foo', 'bar', 3]
a[0] = 1 // [1, 'bar', 3]
Array length property
Arrays have an inner property length
that equals to the amount of array elements. For example:
const a = ['foo', 'bar']
console.log(a.length) // 2
But, there is an interesting moment, as far as you can manually create an Array
item with any index (even not even with number type, that is very bad practice) value of length
property will be counted based on the max numeral index, but not actually by the number of array elements.
For example:
const a = ['foo', 'bar'] // ['foo', 'bar']
a[5] = 'baz' // ['foo', 'bar', empty Ă— 3, 'baz']
console.log(a.length) // 6
typeof Array
At the introduction section, we noticed that arrays are actually objects, so it shouldn’t be a surprise for you:
typeof [] === 'object' // true
How to check if variable is an Array
If the typeof
operator can’t help in Array detection, how we can do it? There is a helper method for that purpose - Array.isArray
:
Array.isArray([]) // true
How to loop over Array items
Instead of using plain for
statement you can use forEach
method, that takes function, which will be executed for each item. This function has 3 parameters:
item
- current item,index
- index of itemarray
- copy of array that calls that function
['a', 'b', 'c'].forEach((item, index) => {
console.log(index, item)
})
// 0 'a'
// 1 'b'
// 2 'c'
How to add item to the end
The method Array.prototype.push
adds a new element and returns a new length of the array:
const a = ['foo', 'bar']
const n = a.push('baz')
console.log(a) // ['foo', 'bar', 'baz']
console.log(n) // 3
How to add item at the start
Array.prototype.unshift
is a similar method to Array.prototype.push
, that do the same but from the start of the array:
const a = [2, 3, 4]
const n = a.unshift(1)
console.log(a) // [1, 2, 3, 4]
console.log(n) // 4
How to remove last item
Array.prototype.pop
removes the last item from Array, and returns removed item:
const a = [1, 2, 'foo']
const lastItem = a.pop()
console.log(a) // [1, 2]
console.log(lastItem) // 'foo'
How to remove first item
Array.prototype.shift
removes the firts item from Array, and returns removed item:
const a = ['foo', 1, 2]
const lastItem = a.shift()
console.log(a) // [1, 2]
console.log(lastItem) // 'foo'
How to replace items in Array
For modifying items, you can use the Array.prototype.splice
method. It has 2 required parameters and list of items as additions:
start
- the start position of modifyingdeleteCount
- number of items, that should be deleted[item1, ...]
- list of new items (not required)
The method returns an array of deleted items.
So, by skipping new items, you can easily remove items from the middle of the array:
const a = [1, 2, 3]
const removedItems = a.splice(1, 1)
console.log(a) // [1, 3]
console.log(removedItems) // [2]
By adding an item you can replace the existing item:
const a = [1, 2, 3]
const removedItems = a.splice(1, 1, 'foo')
console.log(a) // [1, 'foo', 3]
console.log(removedItems) // [2]
How to find item position in Array
Array.prototype.indexOf
returns the index of existed arrays item or -1
otherwise:
const a = [1, 2, 3]
const index = a.indexOf(2)
console.log(index) // [1]
With this method, you can often see a tilda (~
) operand. It uses for checking if the item presents in the array (in other words ~
with -1
will return 0
, that means the absence of item). But, it isn’t the best practice for this purpose, using the Array.prototype.includes
method will be a better solution.
How to find last item position in Array
If you want to get the last index of the item, you have to use the Array.prototype.lastIndex
method:
const a = [1, 1, 1]
const lastIndex = a.lastIndexOf(1)
console.log(lastIndex) // [2]
How to sort an Array
There is a built-in method for sorting array elements - Array.prototype.sort
. This method considers all items as strings and sorts them in alphabetical order:
const a = ['a', 'c', 'b']
a.sort() // ['a', 'b', 'c']
But, due to this behavior, we have an issue with sorting a number of items. Because when we compare '11'
, '3'
- 11
would be less. To solve this issue we have to use a compare function
. Compare function defines elements ordering according to the returning value. It uses 2 parameters (a
, b
) to set the rule of sorting. When compare function returns a negative result (negative number) a
is sorted before b
. When compare function returns a positive result a
is sorted after b
. And the order stays the same for 0
as a result.
For example:
[1, 2, 11].sort() // [1, 11, 2]
[1, 2, 11].sort((a, b) => a - b) // [1, 2, 11]
[1, 2, 11].sort((a, b) => b - a) // [11, 2, 1]
Array Iteration methods
ES6 presented a lot of useful Iteration methods for Array. * All iteration methods take a function as a parameter, that will be executed for each array item.
Array.map
Array.prototype.map
returns a new array based on array modification:
const a = [1, 2, 3]
const b = a.map((item) => item * 2)
console.log(a) // [1, 2, 3]
console.log(b) // [2, 4, 6]
Array.filter
Array.prototype.filter
returns a new array based on the result of inner condition function. (Item will be present in the result array if the function returns true
for that item):
const a = [1, 2, 3]
const b = a.filter((item) => item >= 2)
console.log(a) // [1, 2, 3]
console.log(b) // [2, 3]
Array.reduce
Array.prototype.reduce
returns a single value that accumulates inside the inner function. (The function has the same interface as the previous ones, but as the first parameter has an addition accumulated value. And after this function you can pass the initial value of the accumulated value):
const a = [1, 2, 3]
const sum = a.reduce((result, item) => result + item, 0)
console.log(a) // [1, 2, 3]
console.log(sum) // 6
Array.every
Array.prototype.every
checks if the each item of array satisfie the condition:
const a = [1, 2, -1, 3]
const isPos = a.every((item) => item > 0)
console.log(isPos) // false
Array.some
Array.prototype.some
checks if each item of array satisfies the condition:
const a = [1, 2, -1, 3]
const isPos = a.some((item) => item > 0)
console.log(isPos) // true
Array.find
Array.prototype.find
returns the first item that satisfies the condition:
const a = [1, 2, -1, 'foo', 3, 'bar']
const str = a.find((item) => typeof item === 'string')
console.log(str) // 'foo'
How to reverse Array
Array.prototype.reverse
reverses the existing array:
const a = [1, 2, 3]
a.reverse() // [3, 2, 1]
How to merge Arrays
To merge two arrays you can use Array.prototype.concat
method. It takes arrays that will be merged into a new array:
const a = [1, 2, 3]
const b = [4, 5, 6]
const c = a.concat(b)
console.log(a) // [1, 2, 3]
console.log(b) // [4, 5, 6]
console.log(c) // [1, 2, 3, 4, 5, 6]
Also, you can use the spread
operator:
const a = [1, 2, 3]
const b = [4, 5, 6]
const c = [...a, ...b]
console.log(a) // [1, 2, 3]
console.log(b) // [4, 5, 6]
console.log(c) // [1, 2, 3, 4, 5, 6]
How to check if an item is present in Array
We’ve considered Array.prototype.indexOf
methods and told that checking if element presents in the Array, not the most elegant solution. But we can’t say this about Array.prototype.includes
:
const a = [1, 2, 3]
const isValue = a.includes(2)
console.log(isValue) // true
Advanced section:
In that section, we are going to consider a little more specific topics about arrays.
Spared arrays
As we mentioned in the section of creating an array, there is some special type of arrays - spared arrays. They are arrays that contain empty items.
For example, when you create an instance of an array with Array
constructor and pass to it a single number will be created spared arrays:
const a = new Array(3) // [empty Ă— 3]
console.log(a.length) // 3
So what does it mean? If you try to get an item by index you will get undefined
. Actually, it isn’t undefined
, but some special type - empty slot
. It means that an array doesn’t have item at this position (index).
And you can make sure using in
operator:
const a = new Array(3) // [empty Ă— 3]
console.log(1 in a) // false
Other Cases of getting empty slots
- Array literal notation with empty items between commas:
const a = [,,,] // [empty Ă— 3]
const b = [1,,2] // [1, empty, 2]
const c = [1, 2,] // [1, 2] -> addition coma at the end is ignored
- By using
delete
operator:
const a = [1, 2, 3] // [1, 2, 3]
delete a[1] // [1, empty, 3]
- By setting an item by index:
const a = [] // []
a[5] = 1 // [empty Ă— 5, 1]
When spared arrays are helpful
You might be wondering about the necessity of this arrays feature. But, it is very important from a performance point of view.
When you create an Array of 100000 items with new Array(100000)
your browser doesn’t actually store 100000 items (allocates memory for that), and when you use the iterates methods, they will ignore all of there holes:
const a = new Array(3) // [empty Ă— 3]
a.push('foo') // [empty Ă— 3, 'foo']
a.map((item, index) => index) // [empty Ă— 3, 3]
a.forEach((item) => console.log(item)) // 'foo'
a.every((item) => item === 'foo') // true
From the other hand, it can be a source of issues when you initialize a new array, and your iterate methods don’t perform on it. So, it’s important to keep in mind this type of arrays.
Spread operator with spared arrays
Be careful with spread operator
used to spared arrays, because it changes all holes on the undefined
value:
[...new Array(3)] // [undefined, undefined, undefined]
How to fill an array with value
Array.prototype.fill
sets a passed argument to each array cell, even to the empty slot:
new Array(3).fill(1) // [1, 1, 1]
[1, 2, 3].fill(1) // [1, 1, 1]
How to create an Array from array-like objects
We have already had a brief introduction to the Array.from
method, but it gives much more power for transforming iterable, array-like types to the true arrays.
With Array.from
you can easily transform Set/Map to the array:
const set = new Set([1, 2, 3]) // {1, 2, 3}
const map = new Map([['a', 1], ['b', 2]]) // {'a' => 1, 'b' => 2}
Array.from(set) // [1, 2, 3]
Array.from(map) // [['a', 1], ['b', 2]]
Also, you can use an array-like object with the length
property:
const a = Array.from({ length: 3 }) // [undefined, undefined, undefined]
And you can pass the second argument as map function:
const a = Array.from({ length: 3 }, (item, index) => index) // [0, 1, 2]
How to remove all duplicates from an Array
From the previous section, you might wonder how we can use effective transforming Set into Array with the Array.from
method. It’s a great way to remove all duplicates:
const a = [1, 2, 2, -1]
const s = new Set(a)
const unique = Array.from(s) // [1, 2, -1]