المعرفة:: JavaScript الحالة::مؤرشفة المراجع:: The Complete JavaScript Course 2022 From Zero to Expert, JavaScript Essential Training
Creating and Filling Arrays
- Manual way.
const arr = [1, 2, 3, 4, 5, 6, 7];
- Array constructor.
console.log(new Array(1, 2, 3, 4, 5, 6, 7));
- Empty array and
fill
method.fill()
method changes all elements in an array to a static value, from a start index (default 0) to an end index (defaultarray.length
). It returns the modified array.
const x = new Array(7);
x.fill(1); // [1, 1, 1, 1, 1, 1, 1]
// fill(value, start, end)
x.fill(1, 3, 5); // [empty, empty, empty, 1, 1, empty, empty]
- From constructor.
- The
Array.from()
static method creates a new, shallow-copied Array instance from an array-like or iterable object.
- The
// Array.from(arrayLike, (element, index)
const y = Array.from({ length: 7 }, () => 1); // [1, 1, 1, 1, 1, 1, 1]
const z = Array.from({ length: 7 }, (_, i) => i + 1); // [1, 2, 3, 4, 5, 6, 7]
// Array from a String
Array.from("foo"); // [ "f", "o", "o" ]
// Array from a Set
const set = new Set(["foo", "bar", "baz", "foo"]);
Array.from(set); // [ "foo", "bar", "baz" ]
// Array from a Map
const map = new Map([
[1, 2],
[2, 4],
[4, 8],
]);
Array.from(map); // [[1, 2], [2, 4], [4, 8]]
// Array from a NodeList
// Create an array based on a property of DOM Elements
const sources = Array.from(document.getElementsByTagName("img"), image => image.src);
// This also works but we need to do the mapping separately
const images = [...document.querySelectorAll("img")];
Methods
.length
: Array’s elements count.
Adding items
.push
: Appends an item to the array..unshift
: Add an item to the array at the beginning.
Removing Items
.shift
: Removes an item from the array’s beginning..pop
: Removes an item from the array’s end.
Removing an Item by its index
// If you know the index of an item, you can remove it from the array using splice()
arr.splice(index, 1);
Finding
indexOf
: returns the first index at which a given element can be found in the array, or -1 if it is not present.includes()
: determines whether an array includes a certain value among its entries, returningtrue
orfalse
as appropriate.
Slice
Extract a part of an array without changing the original array. Similar to slice in strings.
let arr = ["a", "b", "c", "d", "e"];
// SLICE
console.log(arr.slice(2)); // ['c', 'd', 'e']
// End parameter isn't included
console.log(arr.slice(2, 4)); // ['c', 'd']
console.log(arr.slice(-2)); // ['d', 'e']
// Get the last element of an array
console.log(arr.slice(-1)); // ['e']
// In ES2022 We can do this instead, note it return a variable not an array
console.log(arr.at(-1)); // 'e'
console.log(arr.slice(1, -2)); // ['b', 'c']
// Create a shallow copy of the array
console.log(arr.slice()); // ['a', 'b', 'c', 'd', 'e']
// Same with spread operator
console.log([...arr]); // ['a', 'b', 'c', 'd', 'e']
Splice
Similar to slice, but changes the array content directly.
// SPLICE
console.log(arr.splice(2)); // ['c', 'd', 'e']
console.log(arr); // ['a', 'b']
// Remove last element using splice
arr.splice(-1);
// Remove last element using pop
arr.pop();
arr.splice(1, 2); // ['a', 'd']
Reverse
Reverses an array, changes the original array.
// REVERSE
const arr2 = ["j", "i", "h", "g", "f"]; // ['f', 'g', 'h', 'i', 'j']
console.log(arr2.reverse());
console.log(arr2);
Concat
Merges two arrays.
// CONCAT
const arr = ["a", "b", "c", "d", "e"];
const arr2 = ["j", "i", "h", "g", "f"];
const letters = arr.concat(arr2);
console.log(letters); // ['a', 'b', 'c', 'd', 'e', 'j', 'i', 'h', 'g', 'f']
// Can be done also using spread
console.log([...arr, ...arr2]);
Join
Joins an array items into a string.
console.log(letters.join(" - "));
At
at()
method takes an integer value and returns the item at that index, allowing for positive and negative integers.
const arr = [23, 11, 64];
console.log(arr[0]); // 23
console.log(arr.at(0)); // 23
Getting last array element
console.log(arr[arr.length - 1]);
console.log(arr.slice(-1)[0]);
console.log(arr.at(-1));
Data Transformation
Map
- Similar to the forEach method, but returns a new array containing the results of applying an operation on all original array elements.
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
const eurToUsd = 1.1;
const movementsUSD = movements.map(function (mov) {
return mov * eurToUsd;
});
const movementsUSD = movements.map(mov => mov * eurToUsd);
// Same as
const movementsUSDfor = [];
for (const mov of movements) movementsUSDfor.push(mov * eurToUsd);
console.log(movementsUSDfor);
Filter
- Returns a new array containing the array elements that passed a specified test condition. It can also access the current item index and whole array second and third parameters.
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
const deposits = movements.filter(function (mov, i, arr) {
return mov > 0;
});
const withdrawals = movements.filter(mov => mov < 0);
console.log(withdrawals);
// Same as
const depositsFor = [];
for (const mov of movements) if (mov > 0) depositsFor.push(mov);
console.log(depositsFor);
Reduce
- Boils (“reduces”) all array elements down to one single value (e.g. adding all elements together) (Snowball). It returns only a reduced value.
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
// accumulator -> SNOWBALL
const balance = movements.reduce(function (accumulator, current, i, arr) {
console.log(`Iteration ${i}: ${accumulator}`);
return accumulator + current;
}, 0); // 0 is the initial value of the accumulator
const balance = movements.reduce((accumulator, current) => accumulator + current, 0);
// Same as
let balance2 = 0;
for (const mov of movements) balance2 += mov;
console.log(balance2);
// Find array maximum value
const max = movements.reduce((acc, mov) => {
if (acc > mov) return acc;
else return mov;
}, movements[0]);
const max = movements.reduce((acc, mov) => acc > mov ? acc : mov}, movements[0]);
console.log(max);
Chaining Data Transformation Methods
- Many array methods can be chained to perform powerful data transformations.
reduce
doesn’t return an array but a value instead, and thus it can’t be chained to another method.
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
const eurToUsd = 1.1;
// PIPELINE
const totalDepositsUSD = movements.filter(mov => mov > 0).map(mov => mov * eurToUsd).reduce((acc, mov) => acc + mov, 0);
console.log(totalDepositsUSD); // 5522.0000000000001
// In order to make debugging easier, other method parameters can be used
.map((mov, i, arr) => {
// console.log(arr);
return mov * eurToUsd;
})
Find
- Can be used to retrieve one array’s element based on a certain condition.
- Unlike
filter
, it won’t return a new array, but the first element that matches the finding condition. Because of this, it can be more efficient in situations when something needs to be done in case of a match.
const firstWithdrawal = movements.find(mov => mov < 0);
const account = accounts.find(acc => acc.owner === "Jessica Davis");
findIndex
- Similar to find, but returns the found element index and not the element itself.
const index = accounts.findIndex(acc => acc.username === currentAccount.username);
Some and Every
- Similar to
includes
, but check for a condition instead of equality. - Some: returns true if the condition is true for any element.
- Every: returns true if the condition is true for all elements.
// EQUALITY
console.log(movements.includes(-130));
// SOME: CONDITION
console.log(movements.some(mov => mov === -130)); // Same as movements.includes(-130)
const anyDeposits = movements.some(mov => mov > 0);
console.log(anyDeposits);
// EVERY
console.log(movements.every(mov => mov > 0));
console.log(account4.movements.every(mov => mov > 0));
- Checking condition can be written as a separate function, then passed as callback to every/some methods.
// Separate callback
const deposit = mov => mov > 0;
console.log(movements.some(deposit));
console.log(movements.every(deposit));
console.log(movements.filter(deposit));
Flat and flatMap
- Introduced in ES2019.
flat
creates a new array with all sub-array elements concatenated into it recursively up to the specified depth (defaults to 1).flat
method removes empty slots in arrays.
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat()); // [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2)); // [0, 1, 2, [3, 4]] - depth 2
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const arr5 = [1, 2, , 4, 5];
arr5.flat(); // [1, 2, 4, 5]
flatMap
returns a new array formed by applying a given callback function to each element of the array, and then flattening the result by one level. Equal toarr.map(...args).flat()
.- Note that with
flatMap
only one level is flattened, so if there’s a need for flattening deepermap
thenflat
must be used.
// flat
const overalBalance = accounts
.map(acc => acc.movements)
.flat()
.reduce((acc, mov) => acc + mov, 0);
console.log(overalBalance);
// flatMap
const overalBalance2 = accounts.flatMap(acc => acc.movements).reduce((acc, mov) => acc + mov, 0);
console.log(overalBalance2);
Sort
sort
method sorts items by alphabetical order.- It changes the original array. This can be avoided by calling
slice
on the original array before sorting.
const owners = ["Jonas", "Zach", "Adam", "Martha"];
console.log(owners.sort()); // ['Adam', 'Jonas', 'Martha', 'Zach']
console.log(owners); // ['Adam', 'Jonas', 'Martha', 'Zach']
- Numbers are being treated as strings.
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
console.log(movements.sort()); // [-130, -400, -500, 1300, 200, 3000, 450, 70]
-
To deal with numbers properly we can use a callback function that takes two parameters:
current
andnext
, and should return:< 0
to sortcurrent
beforenext
. (return something less than zero to keep order)> 0
to sortcurrent
afternext
. (return something higher than zero to switch order)- - to keep original order of
current
andnext
.
-
To compare numbers instead of strings, the compare function can subtract b from a. The following function will sort the array in ascending order (if it doesn’t contain
Infinity
andNaN
).
// return < 0, A, B (keep order)
// return > 0, B, A (switch order)
// Ascending
movements.sort((a, b) => {
if (a > b) return 1;
if (a < b) return -1;
});
movements.sort((a, b) => a - b);
// Descending
movements.sort((a, b) => {
if (a > b) return -1;
if (a < b) return 1;
});
movements.sort((a, b) => b - a);
Summary: Which Array Method to Use?
To mutate original array
Add to original
.push
(end).unshift
(start)
Remove from original
.pop
(end).shift
(start).splice
(any)
Others
.reverse
.sort
.fill
A new array
Computed from original
.map
(loop)
Filtered using condition
.filter
Portion of original
.slice
Adding original to other
.concat
Flattening the original
.flat
.flatMap
An array index
Based on value
.indexOf
Based on test condition
.findIndex
An array element
Based on test condition
.find
Know if array includes
Based on value
.includes
Based on test condition
.some
.every
To transform to value
Based on accumulator
.reduce
(Boil down array to single value of any type: number, string, boolean, or even new array or object)
A new string
Based on separator string
.join
To just loop array
Based on callback
.forEach
(Does not create a new array, just loops over it)
JavaScript Essential Training Notes
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Arrays https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods
/**
* Working with arrays
*/
let item = "flashlight";
const collection = ["Piggy", item, 5, true];
console.log(collection);
console.log(collection.length); // 4
console.log(collection[2]);
collection[2] = "Camera";
collection[collection.length] = "new item"; // Appends a new item at index 4
collection[9] = "at the end";
console.log(collection[8]); // undefined
collection[collection.length - 1]; // the last item in the array
// Finding items in an array
const birds = ["Parrot", "Falcon", "Owl"];
console.log(birds.indexOf("Owl")); // 2
console.log(birds.indexOf("Rabbit")); // -1
// Adding items
const myArray = ["Manchester", "Liverpool"];
myArray.push("Cardiff");
console.log(myArray); // ["Manchester", "Liverpool", "Cardiff"]
myArray.push("Bradford", "Brighton");
console.log(myArray); // ["Manchester", "Liverpool", "Cardiff", "Bradford", "Brighton"]
const newLength = myArray.push("Bristol");
console.log(newLength); // 6
// To add an item to the start of the array, use unshift():
const myArray = ["Manchester", "Liverpool"];
myArray.unshift("Edinburgh");
console.log(myArray); // ["Edinburgh", "Manchester", "Liverpool"]
// Removing items
const myArray = ["Manchester", "Liverpool"];
myArray.pop();
console.log(myArray); // ["Manchester"]
const myArray = ["Manchester", "Liverpool"];
const removedItem = myArray.pop();
console.log(removedItem); // "Liverpool"
// To remove the first item from an array, use shift():
const myArray = ["Manchester", "Liverpool"];
myArray.shift();
console.log(myArray); // ["Liverpool"]
// If you know the index of an item, you can remove it from the array using splice():
myArray.splice(index, 1);
// Accessing every item
const birds = ["Parrot", "Falcon", "Owl"];
for (const bird of birds) {
console.log(bird);
}
// Converting between strings and arrays
const myData = "Manchester,London,Liverpool,Birmingham,Leeds,Carlisle";
const myArray = myData.split(","); // ["Manchester", "Liverpool", ...]
const myNewString = myArray.join(","); // 'Manchester,London,...'
const dogNames = ["Rocket", "Flash", "Bella", "Slugger"];
dogNames.toString(); // Rocket,Flash,Bella,Slugger
// Manipulating array items without modifying the array itself
let backpackContents = ["piggy", "headlamp", "pen"];
backpackContents.forEach(function (item) {
item = `<li>${item}</li>`;
console.log(item);
});
// Apply a fuction
let longItems = backpackContents.find(function (item) {
if (item.length >= 5) {
return item;
}
});
console.log("longItems:", longItems); // longItems: piggy
const deskArray = ["pen", "camera", "phone", "notebook", "headphones", "lightbulb", "usb drive"];
// Add last item as the first item on the array:
deskArray.unshift(deskArray.pop());
console.log("Last item is now first:", deskArray);
// Sort items by alphabetical order:
deskArray.sort();
console.log("Sorted array:", deskArray);
// Find "notebook":
const foundItem = deskArray.find(item => item === "notebook");
console.log("Found item:", foundItem);
// Find and remove an item:
let remove = "notebook";
deskArray.splice(deskArray.indexOf(remove), 1);
console.log(`Array with "${remove}" removed:`, deskArray);
Using the map array method
/**
* The map() array method.
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
*/
const stuff = ["piggy", "headlamp", "pen", "pencil", "eraser", "water bottle"];
const article = document.querySelector("article");
let stuffList = document.createElement("ul");
// map() through the stuff array to make a new stuffItems array.
const stuffItems = stuff.map(item => {
let listItem = document.createElement("li");
listItem.innerHTML = item;
return listItem;
});
// Append each element from the stuffItems array to the stuffList <ul>
stuffItems.forEach(item => {
stuffList.append(item);
});
// Append stuffList to the <article>
article.append(stuffList);