Declaration
let fruits = new Array("Apple", "Pear", "etc")
// mix of values + training comma are allowed
let arr = [ 'Apple', { name: 'John' }, true, function() { alert('hello') }, ]
Access via brackets []
fruits[0] // Apple
arr[1].name // John
arr[3]() // hello
arr[arr.length - 1]() // hello
Access via .at() Accepts negative numbers.
fruits.at(0) // Apple
arr.at(1).name // John
arr.at(3)() // hello
arr.at(-1)() // hello
Change via brackets MUTATES!
fruits[2] = 'Pear' // now ["Apple", "Orange", "Pear"]
fruits[3] = 'Lemon' // now ["Apple", "Orange", "Pear", "Lemon"]
Change via with()
const correctionNeeded = [1, 1, 3]
correctionNeeded.with(1, 2) // => [1, 2, 3]
correctionNeeded // => [1, 1, 3]
Delete MUTATES!
let arr = ["I", "study", "JavaScript", "right", "now"]
delete arr[1];
arr // ["I", empty, "JavaScript", "right", "now"]
arr.length = 3 // truncate
arr // ["I", empty, "JavaScript"]
arr.length = 0
arr // []
Arrays is reference type
let fruits = ["Banana"]
let arr = fruits // copy by reference (two variables reference the same array)
arr.push("Pear") // modify the array by reference
fruits // Banana, Pear - 2 items now
Arrays is an ordered collection Arrays is an ordered collection & we can destroy array speed if: Add a non-numeric property like arr.test = 5 Make holes like arr[0] , arr[1000] & nothing between Fill an array in the reverse order, like arr[1000] , arr[999] and so on. Keys, values, entries
let arr = ['a', 'b', 'c']
// object methods
Object.keys(arr) // ['0', '1', '2']
Object.values(arr) // ['a', 'b', 'c']
Object.entries(arr) // [["0",1],["1",2],["2",3]]
// array iterator methods
const iterator = arr.values(); // returns a new Array Iterator object that contains the values for each index in the array
for (const value of iterator) console.log(value); // a // b // c
const iterator = arr.keys(); // returns a new Array Iterator object that contains the keys for each index in the array.
for (const key of iterator) console.log(key); // 0 // 1 // 2
const iterator = arr.entries();
for (const entry of iterator) console.log(entry); // [0, "a"] // [1, "b"] // [2, "c"]
Length
let arr = [1, 2, 3, 4, 5]
arr.length // 5 // greatest numeric index plus one
arr[123] = "Apple"
arr // [1, 2, 3, 4, 5, empty × 118, "Apple"]
arr.length // 124
arr.length = 2 // truncate to 2 elements
arr // [1, 2]
arr.length = 124 // return length back
arr // [1, 2, empty × 122]
arr[3] // undefined
arr.length = 0 // simplest way to clear the array
arr // []
Multidimensional arrays
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
matrix[1][1] // 5
Loops For
for (let i = 0; i < arr.length; i++) {
alert(arr[i]);
}
for..of
for (let fruit of arr) {
alert(fruit); // no access to index, only to a value
}
for..in DO NOT USE!!!
// came from object, 100 times slower
for (let key in arr) {
alert(arr[key]);
}
forEach
arr.forEach(function(item, index, array) {
alert(`${item} is at index ${index} in ${array}`);
});
Array.isArray()
typeof {} // object
typeof [] // object
Array.isArray({}) // false
Array.isArray([]) // true
Array.from() Returns a new shallow-copied array instance from iterable object
let arrayLike = { 0: "Hello", 1: "World", length: 2};
let arr = Array.from(arrayLike); // ["Hello", "World"]
let arrLike = $('textarea'); // S.fn.init(4) [#word-textarea, #tranalstion-textarea, #example-textarea, #category-textarea, prevObject: S.fn.init(1)]
let arr = Array.from(arrayLike); // [#word-textarea, #tranalstion-textarea, #example-textarea, #category-textarea]
push() MUTATES!
let arr = ["Apple", "Orange", "Pear"]
arr.push("Lemon") // 4 // arr = ["Apple", "Orange", "Pear", "Lemon"]
arr.push("Orange", "Peach") // 6
arr // ["Apple", "Orange", "Pear", "Lemon", "Orange", "Peach"]
pop() MUTATES!
let arr = ["Apple", "Orange", "Pear"]
arr.pop() // "Pear"
arr // ["Apple", "Orange"]
unshift() MUTATES!
// SLOW!
let arr = ["Apple", "Orange", "Pear"]
arr.unshift("Lemon") // 4
arr // ["Lemon", "Apple", "Orange", "Pear"]
arr.unshift("Orange", "Peach") // 6
arr // ["Orange", "Peach", "Lemon", "Apple", "Orange", "Pear"]
shift() MUTATES!
// SLOW!
let arr = ["Apple", "Orange", "Pear"]
arr.shift() // "Apple"
arr // ["Orange", "Pear"]
String()
// returns a comma-separated list of elements
let arr = ["Apple", "Orange", "Pear"];
String(arr); // "Apple,Orange,Pear"
toString()
const arr = [1, 2, 'a', '1a']
arr.toString() // "1,2,a,1a"
arr // [1, 2, 'a', '1a']
toLocaleString()
const arr = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
arr.toLocaleString('en', { timeZone: 'UTC' }); // "1,a,12/21/1997, 2:12:00 PM"
splice() MUTATES! arr.splice(startIndex, [deleteCount], [elemToInsert1], [elemToInsert2]) arr.splice(index, 1) - remove one element Remove an item by index position modifies arr starting from the startIndex removes deleteCount number of elements inserts elem1, ..., elemN at their place Returns the array of removed elements
// remove el
let arr = ["I", "study", "JavaScript"]
arr.splice(1, 1) // ["study"] // Starting from the index 1 remove 1 el
arr // ["I", "JavaScript"]
// remove & replace els
let arr = ["I", "study", "JavaScript", "right", "now"]
arr.splice(0, 3, "Let's", "dance") // ) ["I", "study", "JavaScript"]
arr // ["Let's", "dance", "right", "now"]
// insert the elements w/o any removals
let arr = ["I", "study", "JavaScript"]
arr.splice(2, 0, "complex", "language") // []
arr // ["I", "study", "complex", "language", "JavaScript"]
// Negative indexes are allowed
// index -1 (one step from the end)
let arr = [1, 2, 5]
arr.splice(-1, 0, 3, 4) // []
arr // [1, 2, 3, 4, 5]
toSpliced()
const months = ["Jan", "Mar", "Apr", "May"];
// Inserting an element at index 1
const months2 = months.toSpliced(1, 0, "Feb");
console.log(months2); // ["Jan", "Feb", "Mar", "Apr", "May"]
// Deleting two elements starting from index 2
const months3 = months2.toSpliced(2, 2);
console.log(months3); // ["Jan", "Feb", "May"]
// Replacing one element at index 1 with two new elements
const months4 = months3.toSpliced(1, 1, "Feb", "Mar");
console.log(months4); // ["Jan", "Feb", "Mar", "May"]
// Original array is not modified
console.log(months); // ["Jan", "Mar", "Apr", "May"]
slice() arr.slice([beginIndex], [endIndex]) returns new array copying all items from beginIndex to endIndex (not including end) start & end can be negative, in that case position from end is assumed
let arr = ["t", "e", "s", "t"];
arr.slice(1, 3); // ["e", "s"] (copy from 1 to 3)
arr // ["t", "e", "s", "t"]
arr.slice(-2); // ["s", "t"] (copy from -2 to the end)
arr // ["t", "e", "s", "t"]
let newArr = arr.slice(); // ["t", "e", "s", "t"] // created a copy
arr // ["t", "e", "s", "t"]
concat() arr.concat(arg1, arg2)
const arr = [1, 2]
const newArr = arr.concat([3, 4]) // [1, 2, 3, 4]
arr // [1, 2]
arr.concat([3, 4], [5, 6]) // [1,2,3,4,5,6]
arr.concat([3, 4], 5, 6) // [1,2,3,4,5,6] // arr = [1, 2]
Make iterable concatable
let arr = [1, 2]
let arrayLike = {
0: "something",
length: 1,
}
arr.concat(arrayLike) // [1,2,[object]]
let arr = [1, 2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2,
};
arr.concat(arrayLike) //[1, 2, "something", "else"]
indexOf(), lastIndexOf() arr.indexOf(item, [fromIndex])
// looks for item starting from index from, and returns the index where it was found, otherwise -1.
// same methods as for strings
let arr = [1, 0, false, 1];
arr.indexOf(0) // 1
arr.indexOf(false) // 2
arr.indexOf(null) // -1
// same, but looks for from right to left
arr.lastIndexOf(1) // 3
includes() arr.includes(item, [fromIndex])
// looks for item starting from fromIndex, returns true if found
arr.includes(1) // true
// indexOf() vs includes()
[NaN].indexOf(NaN) // -1 (should be 0, but === equality doesn't work for NaN)
[NaN].includes(NaN) // true
reverse() MUTATES!
const items = [1, 2, 3];
console.log(items); // [1, 2, 3]
items.reverse();
console.log(items); // [3, 2, 1]
toReversed()
const sequence = [1, 2, 3];
sequence.toReversed(); // => [3, 2, 1]
sequence; // => [1, 2, 3]
split()
let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);
arr; // [Bilbo, Gandalf]
"test".split('') // ["t", "e", "s", "t"]
join()
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';'); // glue the array into a string using ;
str; // Bilbo;Gandalf;Nazgul
fill() MUTATES! arr.fill(value, [startIndex], [endIndex])
let arr = [1, 2, 3, 4];
arr.fill(0, 2, 4); // [1, 2, 0, 0] // fill with 0 from position 2 until position 4
arr // [1, 2, 0, 0]
arr.fill(5, 1); // [1, 5, 5, 5] // fill with 5 from position 1
arr.fill(6); // [6, 6, 6, 6] // fill all with 6
copyWithin() arr.copyWithin(targetIndex, [startIndex], [endIndex]) copies part of an array to another location in the same array and returns it w/o modifying its length targetIndex - index where to copy. If negative - counted from the end startIndex - index start copying elements from. If negative - counted from the end. Default - 0 endIndex - index end copying elements from. copyWithin() copies up to but not including end. If negative - counted from the end. Default = arr.length
let arr = ['a', 'b', 'c', 'd', 'e'];
arr.copyWithin(0, 3, 4); // ["d", "b", "c", "d", "e"] // copy to index 0 the element at index 3
arr // ["d", "b", "c", "d", "e"]
arr.copyWithin(1, 3); // ["d", "d", "e", "d", "e"] // copy to index 1 els from index 3 to the end
flat() arr.flat([depth]) returns a new array with concatenated sub-array elements with specified depth. depth - The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
let arr = [0, 1, 2, [3, 4]]
arr.flat() // [0, 1, 2, 3, 4]
arr // [0, 1, 2, [3, 4]] // not mutated
let arr = [0, 1, 2, [[[3, 4]]]]
arr.flat(2) // [0, 1, 2, [3, 4]]
arr.flat() // [0, 1, 2, [[3, 4]]]
[1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]].flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
map() let result = arr.map(function(item, [index], [array]) {...}, [thisArg]); method calls the function for each element of the array returns an array of function returns It is identical to a map() followed by a flat() of depth 1
let arr = ["Bilbo", "Gandalf", "Nazgul"]
arr.map(item => item.length) // [5, 7, 6]
arr // ["Bilbo", "Gandalf", "Nazgul"]
flatMap() arr.flatMap(function callbackFn(currentValue, [index], [array]) {...}, [thisArg]) method returns a new array formed by applying a given callback function to each element of the array Result is flattened by one level It is identical to a map() followed by a flat() of depth 1
var arr = [1, 2, 3, 4];
arr.flatMap(x => [x, x * 2]); // [1, 2, 2, 4, 3, 6, 4, 8]
arr // [1, 2, 3, 4]
sort() MUTATES! returns sorted modified array sort(function compareFn(firstEl, secondEl) {...}) comparison function is required to return a positive number to say “greater” and a negative number to say “less”.
let arr = [ 1, 2, 15 ]
arr.sort() // [1, 15, 2] // items are sorted as strings by default
arr // 1, 15, 2
function compareFn(firstEl, secondEl) {
if (firstEl > secondEl) return 1; // if the first value is greater than the second
if (firstEl == secondEl) return 0; // if values are equal
if (firstEl < secondEl) return -1; // if the first value is less than the second
}
arr.sort(compareFn);
arr // 1, 2, 15
// shorter function
let arr = [ 1, 2, 15 ]
arr.sort(function(a, b) { return a - b })
arr // 1, 2, 15
// or even shorter with an arrow fn
[ 1, 2, 15 ].sort( (a, b) => a - b ); // [1, 2, 15]
['Österreich', 'Andorra', 'Vietnam'].sort(); // ["Andorra", "Vietnam", "Österreich"]
['Österreich', 'Andorra', 'Vietnam'].sort( (a, b) => a.localeCompare(b) ); // ["Andorra", "Österreich", "Vietnam"]
toSorted()
const outOfOrder = new Uint8Array([3, 1, 2]);
outOfOrder.toSorted(); // => Uint8Array [1, 2, 3]
outOfOrder; // => Uint8Array [3, 1, 2]
filter() arr.filter(function(element, [index], [array]) {...}, [thisArg]) returns a new array of all matching elements if 'true' item is pushed to results and the iteration continues returns empty array if nothing found
// returns array of the first two users
const users = [{id: 1, name: "John"},{id: 2, name: "Pete"}, {id: 3, name: "Felix"}]
let someUsers = users.filter(item => item.id < 3);
someUsers // [{id: 1, name: "John"},{id: 2, name: "Pete"}]
some() arr.some(function(element, [index], [array]) {...}, [thisArg]) method tests if one element in the array passes the test function returns true if it finds an el for which the function returns true, otherwise it returns false
const array = [1, 2, 3, 4, 5]
const even = (el) => el % 2 === 0 // checks whether an element is even
array.some(even) // true
every() arr.every(function(element, [index], [array]) {...}, [thisArg]) method tests whether all elements in the array pass the test function. returns true or false
const isBelowThreshold = (el) => el < 40;
const arr = [1, 30, 39, 29, 10, 13];
arr.every(isBelowThreshold); // true
find() let result = arr.find(function(item, index, array) {}, thisArg) returns index of the first element in the array that passes the test. Otherwise, -1. if fn returns TRUE, item is returned and iteration is stopped for falsy scenario returns undefined index, array, thisArg: optional arguments The find method looks for a single (first) element that makes the function return true.
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1); // user = {id: 1, name: "John"}
user.name; // John
// item argument is used, other arguments of this function are rarely used
findIndex() arr.findIndex(function(item, index, array) {...}, thisArg); returns index of the first element in the array that passes the test. Otherwise, -1.
let index = users.findIndex(item => item.id == 3); // index = 2
findLast() & findLastIndex()
const arr = [1, 2, 3, 1, 2, 3, 1, 2]
const three = arr.find(num => num === 3) // 3
const threeIndex = arr.findIndex(num => num === 3) // 2
const lastThree = arr.findLast(num => num === 3) // 3
const lastThreeIndex = arr.findLastIndex(num => num === 3) // 5
reduce() let value = arr.reduce(function(previousValue, currentValue, [currentIndex], [array]) {...}, [initial]); previousValue – result of the previous function call, equals initial the first time (if initial is provided) currentValue – is the current array item [currentIndex] – is its position [array] – is the array [initial] - A value to use as the first argument the result of the previous function call is passed to the next one as the first argument
[1, 2, 3, 4, 5].reduce((sum, item) => sum + item) // 15
[1, 2, 3, 4, 5].reduce((sum, item) => sum + item, 0) // 15
[1, 2, 3, 4, 5].reduce((sum, item) => sum + item, 10) // 25
arr.reduceRight() // does the same, but goes from right to left