Destructuring Assignment
The two most used data structures in JavaScript are Object and Array.
- Objects allow us to create a single entity that stores data items by key.
- Arrays allow us to gather data items into an ordered list.
Destructuring Assignment is a JavaScript expression that allows to unpack values from arrays, or properties from objects, into distinct variables data can be extracted from arrays, objects, nested objects, and assigning to variables.
My Definition: What actually do we want from Objects and Arrays? Just store them with variables and call them when needed.
Destructuring - Arrays, and Objects by Anisul Islam
//==============================
// Destructuring by Anisul Islam
//==============================
//==
// array destructuring //
//==
let numbers = [10, 20, 30, 40, 50];
// normal method
console.log(numbers[0]);
console.log(numbers[1]);
// destructing method =>
let [num1, num2, num3, num4, num5] = numbers;
// let [num1, num2, num3, ...z] = numbers;
console.log(num1);
console.log(num2);
console.log(num1, num2, num3);
// spread operator
// let [num01, num02, ...z] = numbers;
// console.log(z) // returns: [40, 50]
//==
// swap variables
//==
let a = 10, b = 20;
[a, b] = [b, a];
console.log(a); //returns: 20
console.log(b); // returns: 10
//==
// object destructuring //
//==
const studentInfo = {
id: 101,
fullName : 'Nur Rafi',
gpa: 3.75,
language: {
native: 'Bangla',
beginner: 'English',
}
}
// normal method
console.log(studentInfo.gpa);
// destructing method =>
const {id, fullName, language} = studentInfo;
console.log(fullName, language.native);
//==
// nested object destructuring //
//==
console.log(language.native)
//==
// destructuring function parameters //
//==
const student = {
id: 777,
fullName: 'Nur Rafi',
subject: 'JavaScript'
}
// normal method
const studentData = (student) => {
return console.log(`${student.id}, ${student.fullName}, ${student.subject}`)
};
studentData(student);
// destructing method =>
const studentDataDst = ({id, fullName, subject}) => {
return console.log(`${id}, ${fullName}, ${subject}`)
};
studentDataDst(student);
Destructuring Arrays
// =================== //
// Destructuring Array //
// =================== //
const restaurant = {
name: 'Classico Italiano',
location: 'Via Angelo Tavanti 23, Firenze, Italy',
categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
order: function (starterIndex, mainIndex) {
return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
},
};
const arr = [2, 3, 4];
// normal method
const a = arr[0];
const b = arr[1];
const c = arr[2];
// destructuring method =>
const [x, y, z] = arr; // This is not array, just a Distructuring assignment
console.log(x, y);
console.log(x, y, z);
/// Restaurant Categories ///===>
// first and second
const [first, second] = restaurant.categories;
console.log(first, second);
// first and third
let [main, , secondary] = restaurant.mainMenu; // skipping elements using skip(,)
console.log(main, secondary); // returns: Italian Vegetarian
/// Reverse or Swap or Switching Variables ///===>
// without distructuring =>
const temp = main; // temporary variable
main = secondary;
secondary = temp;
console.log(main, secondary); // returns: Vegetarian Italian
// distructuring method =>
[main, secondary] = [secondary, main]
console.log(main, secondary); // returns: Vegetarian Italian
/// Distructuring Function ///===>
// normal method
const order = restaurant.order(2, 0);
console.log(order) // returns: 'Garlic Bread', 'Pizza'
// destructuring method =>
// Receive 2 return values from a function
const [starterIdx, mainIdx] = restaurant.order(2, 0); // Destruction Assignment = Calling a function with(parameters)
console.log(starterIdx, mainIdx); // Returns: 'Garlic Bread', 'Pizza'
/// Nested Destructuring ///===>
const nested = [2, 4[5, 6]]; // nested = array inside an array
const [i, , j] = nested;
console.log(i, j); // returns 2 [5, 6]
const [i, , [j, k]] = nested;
console.log(i, j, k); // returns: 2, 5, 6
/// Setup Default Values ///===>
// normal method = undefined
const [p, q, r] = [8, 9];
console.log(p, q, r); // returns 8, 9, undefined
// Default Value
const [p = 1, q = 1, r = 1] = [8, 9];
console.log(p, q, r); // returns 8, 9, 1
// This is usefull when we get data from API
Destructuring Objects
// ===================== //
// Destructuring Objects //
// ===================== //
const restaurant = {
name: 'Classico Italiano',
location: 'Via Angelo Tavanti 23, Firenze, Italy',
categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
openingHours: {
thu: {
open: 12,
close: 22,
},
fri: {
open: 11,
close: 23,
},
sat: {
open: 0, // Open 24 hours
close: 24,
},
},
orderDelivery: function({starterIndex, mainIndex, time, address}){
console.log(`Order received! ${this.starterMenu[starterIndex]} and ${this.mainMenu[mainIndex]} will be deliverd to ${address} at ${time}`);
},
};
/// Object Calling function 🙁 ///===>
restaurantName.orderDelivery({
time: '22:30',
address: 'Via del Sole, 21',
mainIndex: 2,
starterIndex: 2,
}); // If there is lots of parameters, 1st write object property then write function parameters.
/// Fundamental of Destructuring Objects ///===>
const {name, openingHours, categories} = restaurant;
console.log(name, openingHours, categories);
// API data comes with Objects, So Destructuring is life saving method of Javascript. Like Weather Data, Movie Data //
/// Setup New Variables ///===>
const {name: restaurantName, openingHours: hours, categories: tags} = restaurant;
// What if we want a new variable name from the property name, So write old name as reference and assign new name.
console.log(restaurantName, hours, tags) // Helpful for dealing with 3rd party data
/// Setup default value which is [empty] ///===>
const {
menu = [], starterMenu: starters = []
} = restaurantName;
console.log(menu, starters); // menu does not exist on restaurent Object so value is [empty]
// If we do not setup default value result will be [undefined]
// In real life API data do not comes with hardcoded like restaurent Object
// We do not know how will be data looks like, So setup default value is useful.
/// Mutating Variables ///===> (Reassign Values to Variables)
let a = 111;
let b = 222;
const obj = {a: 23, b: 7, c: 14};
{a, b} = obj;
console.log(a, b); // returns: Unexpected token error '='
// solution is using parenthesis()
({a, b} = obj);
console.log(a, b); // returns: 23, 7
/// Nested Objects ///===>
const {fri} = openingHours;
console.log(fri); // {open: 11, close: 23}
// but we need open and close separately
const {fri:{open, close}} = openingHours; // we can go more deep like {{{}}}
console.log(open, close);
Spread Operator(...)
// Normal method ==>
let numbers = [10, 20, 30, 40, 50];
function calculate(a, b, c, d, e) {
return a + b + c + d + e
}
console.log(calculate(numbers)); // returns: 10,20,30,40,50undefinedundefinedundefinedundefined
// Destructuring Method ==>
let numbers = [10, 20, 30, 40, 50];
let [num1, num2, num3, num4, num5] = numbers;
const calculate = function(){
return num1 + num2 + num3 + num4 + num5
}
console.log(calculate(numbers)) // returns: 150
// Spread Operator ==>
let numbers = [10, 20, 30, 40, 50];
function calculate(a, b, c, d, e) {
return a + b + c + d + e
}
console.log(calculate(...numbers)); // returns: 150
// Calculate Unlimited number of arguments using Arguments Object
const numbers = [10, 20, 30, 40, 50]
function add() {
let result = 0;
for (let i = 0; i < arguments.length; i++) {
result += arguments[i]; // Same As: x = x + y
};
return result;
};
console.log(add(...numbers)); // SPREAD operator // returns: 150
// ========================= //
// The Spread Operator (...) //
// ========================= //
const restaurant = {
name: 'Classico Italiano',
location: 'Via Angelo Tavanti 23, Firenze, Italy',
categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
openingHours: {
thu: {
open: 12,
close: 22,
},
fri: {
open: 11,
close: 23,
},
sat: {
open: 0, // Open 24 hours
close: 24,
},
},
orderPasta: (ing1, ing2, ing3) => {
console.log(`Here is your delicious pasta with ${ing1}, ${ing2} and ${ing3}`);
},
};
/// BEST use for - Pass arguments into a function or build a new Array
const arr = [7, 8, 9]; // Unpacking all element at one
const badNewArr = [1, 2, arr[0], arr[1], arr[2]];
console.log(badNewArr); // returns: [1, 2, 7, 8, 9]
/// Using Spread Operator(...) ///===>
const newArr = [1,2, ...arr]; // Automatically add comma(,) if there is other element with comma(,)
console.log(newArr); // returns: [1, 2, 7, 8, 9]
console.log(...newArr); // returns: 1 2 7 8 9 // Individual elements in the array
const newMenu = [...restaurant.mainMenu, 'Gnocci'];
console.log(newMenu); // returns: ["Pizza", "Pasta", "Risotto", "Gnocci"]
console.log(...newMenu); // returns: Pizza Pasta Risotto Gnocci
// Spread Operator is bit similer to destructuring because it also helps us get an element out of array.
// Big difference is spread operator take all the element from the array and it also does not create variables.
/// Shallow Copy array ///===>
const mainMenuCopy = [...restaurant.mainMenu]
/// Join Multiple Arrays ///===>
const menu = [...restaurant.starterMenu, ...restaurant.mainMenu]
console.log(menu); // returns: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad", "Pizza", "Pasta", "Risotto"]
// Spread Operator work not only on Arrays basically on all irritable
// What is irritable?
// ==> Iterable: arrays, strings, maps, sets but NOT Objects and Numbers
const str = 'Nur';
const latters = [...str];
console.log(...str); // returns: N u r
console.log(latters); // returns: ['N', 'u', 'r']
console.log(`${...str} Rafi`); // This is not a place that expects multiple value seperated by comma,
const numbers = 35468431;
const numbersStr = [...numbers];
console.log(numbersStr); // returns: TypeError: numbers is not iterable
const ingredients = [prompt("Let's make pasta! Ingredient 1?"), prompt("Ingredient 2?"), prompt("Ingredient 3?")];
console.log(ingredients);
console.log(restaurant.orderPasta(...ingredients));
// Since 2018 Spread Operator(...) also works on Objects even though Objects are not Iterable.
/// Objects ///===>
const newRestaurant = {foundedIn: 2021, ...restaurant, founder: 'This is me'}
console.log(newRestaurant);
/// Shallow Copy Object ///===>
const restaurantCopy = {...restaurant}
console.log(restaurantCopy);
restaurantCopy.name = 'Nur Rafi'
console.log(restaurantCopy.name);
console.log(restaurant.name);
// We can build new Array and Object by copy them using Spread Operator(...) also edit them.
Rest Pattern and Parameters
/// Arguments Object ///===>
function add(a, b) {
return a + b;
}
console.log(2, 5);
/// Calculate Unlimited number of arguments using Arguments Object ///===>
const numbers = [10, 20, 30, 40, 50]
function add() {
let result = 0;
for (let i = 0; i < arguments.length; i++) {
result += arguments[i]; // Same As: x = x + y
}
return result;
}
console.log(add(...numbers)); // SPREAD operator
// Arguments Object NOT available in Arrow function
function add() {
let result = 0;
for (let i = 0; i < arguments.length; i++) {
result += arguments[i]; // Addition Assignment Operator (+=)
}
return result;
}
console.log(add(10, 20)); // returns: ReferenceError: arguments is not defined
Rest Pattern looks exactly like Spread Operator so it has the same syntax with 3dots(...) but it does the opposite of Spread Operator.
// =========================== //
// Rest Pattern and Parameters //
// =========================== //
/// REST Parameter or Unused Parameter ///===>
// SPREAD, because on RIGHT side of =
const arr = [10, 20, ...[30, 40, 50]];
// REST, becuase on LEFT side of =
const [a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // returns: 10
console.log(b); // returns: 20
console.log(rest); // returns: Array [30,40,50]
/// Destructuring using REST parameter(...otherFood) and SPREAD operator(...)=> Add 2 array ///===>
const [pizza, , risotto, ...otherFood] = [...restaurant.mainMenu, ...restaurant.starterMenu];
console.log(pizza, risotto, otherFood); // returns: Pizza Risotto Arrays ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"]
/// Objects ///===>
const {
thu,
fri,
...weekend
} = restaurant.openingHours;
console.log(weekend); // returns: sat: {open: 0, close: 24}
// REST parameter in function
function person(name, age, ...degree) {
console.log(name); // returns: John
console.log(age); // returns: 25
console.log(degree); // returns: Array ['SSC', 'HSC']
}
person('John', 25, 'SSC', 'HSC');
function add(...numbers) {
console.log(numbers)
};
add(2, 3); // returns: [2, 3]
add(2, 3, 4, 5); // returns: [2, 3, 4, 5]
add(2, 3, 4, 5, 6, 7); // returns: [2, 3, 4, 5, 6, 7]
// Calculate Unlimited number of arguments using Arguments Object
const numbers = [10, 20, 30, 40, 50]
function add() {
let result = 0;
for (let i = 0; i < arguments.length; i++) {
result += arguments[i]; // Same As: x = x + y
};
return result;
};
console.log(add(...numbers)); // SPREAD operator // returns: 150
SPREAD Operator and REST Pattern syntax look exactly the same, but they work in opposite ways depending on where it is used.
Rest Pattern separated by commas(,) with variables and Spread Operators separated by commas(,) with values.
In Destructuring, Spread Operator is used on the right side of (=) & Rest Pattern is used on the left side of (=).
Rest Pattern is also known as Unused Parameter. Rest element must be the last element, there must be only one Rest element.
👉🏻 Spread Operator(...) => Spread Array | Unpack Values.
👉🏻 REST Parameter(...) => Compress Array | Pack Values.
Short Circuiting (&& and ||)
Falsy Value: 0, '', undefined, null, NaN(Not a Number)
Practical Use
Short-Circuiting
// ============================ //
// Short Circuiting (&& and ||) //
// ============================ //
/// Falsy Value ///===>
// 0, '', undefined, null, NaN(Not a Number)
console.log(3 || 'Jonas'); // return: 3
console.log('' || 'Jonas'); // return: Jonas
console.log(true || 0); // returns: true
console.log(undefined || null); // returns: null // the is no short-circuiting
console.log(undefined || 0 || '' || 'Hello' || 313 || null) // returns: Hello
/// Setting Default Value ///===>
// Ternary Operator
restaurant.numGuests = 23 // if 0 it will not work and value will be 10
const guest1 = restaurant.numGuests ? restaurant.numGuests : 10;
console.log(guest1);
// OR(||) Operator and Short-Circuiting
restaurant.numGuests = 23 // if 0 it will not work and value will be 10
const guest2 = restaurant.numGuests || 10
console.log(guest2) //
// restaurant.numGuests = 0;
// Both method will not work if the value is 0, but there is other SOLUTION
console.log(0 && 'Jonas'); // returns: 0
console.log(7 && 'Jonas'); // returns: Jonas
console.log('Hello' && 313 || null && undefined) // returns: null
The Nullish Coalescing Operator (??)
// ==================================== //
// The Nullish Coalescing Operator (??) //
// ==================================== //
// ES 2020
// Nullish: null and undefined (NOT 0 or '')
restaurant.numGuests = 0;
const guest = restaurant.numGuests ?? 10
console.log(guest) // return: 0
// 0 and '' is truthy value for Nullish Coalescing Operator
Optional Chaining Operator(.?)
// ============================== //
// Optional Chaining Operator(.?) //
// ============================== //
if (restaurant.openingHours && restaurant.openingHours.mon) console.log(restaurant.openingHours.mon.open) // returns: Error
// WITH Optional Chaining
console.log(restaurant.openingHours.mon?.open);
// MULTIPLE Optional Chaining
console.log(restaurant.openingHours?.mon?.open);
// Example
const shop = {
openingHours: {
thu: {
open: 12,
close: 22,
},
fri: {
open: 11,
close: 23,
},
sat: {
open: 0, // Open 24 hours
close: 24,
},
},
};
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
for (const day of days) {
const open = shop.openingHours[day]?.open; // Using a variable to refer to a property name, we need to use [day] Notation.
console.log(`On ${day}, we open at ${open}`);
// Set Default Value Instead of UNDEFINED using OR(||) Operator
const open = shop.openingHours[day]?.open || 'closed';
console.log(`On ${day}, we open at ${open}`);
// If value is 0 or '' use AND(??) Operator
const open = shop.openingHours[day]?.open ?? 'closed';
console.log(`On ${day}, we open at ${open}`);
};
Enhanced Object Literals
👉🏻 A comma(,) separates each name-value pair from the next.
👉🏻 There should be no comma after the last name-value pair.
If any of the syntax rules are broken, such as a missing comma(,) or colon(:) or curly bracket{}, an error will be thrown.
// ======================== //
// Enhanced Object Literals //
// ======================== //
// 1. Write Variable Name instead of Property Name.
// 2. Write Function Expression instead of Function Declaration with Property Name.
// 3. Compute Property Name instead of writing manually.
const weekdays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
const openingHours = {
weekdays[3]: {
open: 12,
close: 22,
},
weekdays[4]: {
open: 11,
close: 23,
},
[`day-${2 + 4}`]: {
open: 0, // Open 24 hours
close: 24,
},
};
const restaurant = {
name: 'Classico Italiano',
location: 'Via Angelo Tavanti 23, Firenze, Italy',
categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
// Before ES6
openingHours: openingHours,
// ES6 Enhanced Object Literal
openingHours,
order(starterIndex, mainIndex) {
return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
},
orderDelivery({
starterIndex,
mainIndex,
time,
address
}),
};
Looping Arrays: The for-of Loop
// =============================== //
// Looping Arrays: The for-of Loop //
// =============================== //
const restaurant = {
name: 'Classico Italiano',
location: 'Via Angelo Tavanti 23, Firenze, Italy',
categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
mainMenu: ['Pizza', 'Pasta', 'Risotto'],
openingHours: {
thu: {
open: 12,
close: 22,
},
fri: {
open: 11,
close: 23,
},
sat: {
open: 0, // Open 24 hours
close: 24,
},
},
};
const menu = [...restaurant.starterMenu, ...restaurant.mainMenu];
/// 1. Normal Method ///
for (const item of menu) console.log(item);
// returns: each element line by line ==>
Focaccia
Bruschetta
Garlic Bread
Caprese Salad
Pizza
Pasta
Risotto
// NEED to write single line OR use {} brackets for output
// We can use 'continue' and 'break' keywords
// Index/Length will not work here, So we have to use entries()
/// 2. .entries() => Array: [Index with Items] ///
for (const item of menu.entries()) console.log(item);
// returns: each element line by line with index number but look like Array ==>
[0, "Focaccia"]
[1, "Bruschetta"]
[2, "Garlic Bread"]
[3, "Caprese Salad"]
[4, "Pizza"]
[5, "Pasta"]
[6, "Risotto"]
console.log(menu.entries()) // returns: Array Iterator {}
console.log([...menu.entries()]);
// returns: Array Within Arrays ==>
[Array(2), Array(2), Array(2), Array(2), Array(2), Array(2), Array(2)]
/// 3. Used by Normal Method ///
for (const item of menu.entries()) console.log(`${item[0]+1}: ${item[1]}`)
// returns: each item lile by line with index number ==>
1: Focaccia
2: Bruschetta
3: Garlic Bread
4: Caprese Salad
5: Pizza
6: Pasta
7: Risotto
/// 4. Used by Destructuring Method ///
for (const [i, el] of menu.entries()) console.log(`${i+1}: ${el}`);
// returns: each item lile by line with index number ==>
1: Focaccia
2: Bruschetta
3: Garlic Bread
4: Caprese Salad
5: Pizza
6: Pasta
7: Risotto
Looping Objects: Object Keys, Values, and Entries
- Object.keys(obj) – returns an array of keys.
- Object.values(obj) – returns an array of values.
- Object.entries(obj) – returns an array of [key, value] pairs.
// ================================================= //
// Looping Objects: Object Keys, Values, and Entries //
// ================================================= //
const openingHours = restaurant.openingHours // Object
/// Object Keys ///==>
// WITHOUT Loop <===> Array
console.log(Object.keys(openingHours));
// returns: Array: ["thu", "fri", "sat"]
// WITH Loop <===> Line by Line
for(const day of Object.keys(openingHours)) console.log(day);
// returns: List of available Key/Property name of object ==>
fri
sat
thu
console.log(Object.keys(openingHours).length) // returns: Number of properties
const properties = Object.keys(openingHours);
let openStr = `We are open on ${properties.length} days:`;
for(const day of properties){
openStr += ` ${day},` // Sentence + Property with dynamic loop value
};
console.log(openStr)
/// Object Values ///==>
// WITHOUT Loop <===> Array
console.log(Object.values(openingHours));
// WITH Loop <===> Line by Line
for(const value of Object.values(openingHours)) console.log(value);
// returns:
{open: 12, close: 22}
{open: 11, close: 23}
{open: 0, close: 24}
/// Entrie Object ///==>
const entries = Object.entries(openingHours)
console.log(entries) // returns: Index [key, value]
for(const [key, {open, close}] of entries){
console.log(`On ${key} we open at ${open} and close at ${close}`);
};
// returns:
On thu we open at 12 and close at 22
On fri we open at 11 and close at 23
On sat we open at 0 and close at 24
Sets & Maps
- Objects are used for storing keyed collections.
- Arrays are used for storing ordered collections.
But that’s not enough for real life. That’s why Set and Map also exist.
Set
A Set is a special type collection – “set of values” (without keys), where each value may occur only once. There is no Index and no need to get data out of a set. The main use case is to remove duplicate values of a set
- new Set(iterable) – creates the set, and if an iterable object is provided (usually an array), copies values from it into the set.
set.add(value) – adds a value, returns the set itself.set.delete(value) – removes the value, returns true if value existed at the moment of the call, otherwise false.set.has(value) – returns true if the value exists in the set, otherwise false.set.clear() – removes everything from the set.set.size – is the elements count.
The main feature is that repeated calls of set.add(value) with the same value don’t do anything. That’s the reason why each value appears in a Set only once.
// === //
// Set //
// === //
const ordersSet = new Set(['Pasta', 'Pizza', 'Pizza', 'Pasta', 'Sandwich'])
console.log(ordersSet) // returns: Set(3) {"Pasta", "Pizza", "Sandwich"}
console.log(new Set('Rafe')); // returns: Set(4) {"R", "a", "f", "e"}
console.log(ordersSet.size); // returns: 3
console.log(ordersSet.has('Pizza')); // returns: true
console.log(ordersSet.has('Burger')); // returns: false
ordersSet.add('Garlic Bread');
ordersSet.delete('Pizza')
console.log(ordersSet) // returns: Set(4) {"Pasta", "Sandwich", "Garlic Bread"}
ordersSet.clear() // returns: clear set
for (const order of ordersSet) console.log(order)
// Example
const staff = ['Waiter', 'Chef', 'Waiter', 'Manager', 'Chef', 'Waiter'];
// Q: How many different positions are in a restaurent?
const staffUnique = new Set(staff);
console.log(staffUnique.size); // returns: 3
// Convert Set to Array using Spread Operator [...]
const staffArray = [...new Set(staff)];
console.log(staffArray) // returns: ["Waiter", "Chef", "Manager"]
// How many characters in my name
console.log(new Set('nurmohamodrafi').size) // returns: 10
Map
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
Map has 3 default parameters (key, value, map)
Methods and properties are:
- new Map() – creates the map.
map.set(key, value) – stores the value by the key.map.get(key) – returns the value by the key, undefined if key doesn’t exist in map.map.has(key) – returns true if the key exists, false otherwise.map.delete(key) – removes the value by the key.map.clear() – removes everything from the map.map.size – returns the current element count.
// === //
// Map //
// === //
const numbers = [10, 20, 30, 40];
const names = ['Tamim', 'Sakib', 'Musfiq'];
const object = [{
name: 'Humayun Ahmed',
availableBooks: 30
},
{
name: 'Jafar Iqbal',
availableBooks: 20
},
{
name: 'Ahmed Sofa',
availableBooks: 10
},
];
// By Default Map has 3 parameters | ForEach Loop also has 3 parameters
const newNumber = numbers.map(function (currentValue, index, arr) {
console.log(currentValue)
})
// Callback function
const newName = names.map(function (name) {
return name.toUpperCase()
})
console.log(newName); // returns: ["TAMIM", "SAKIB", "MUSFIQ"]
// Arrow function
const newNameArr = names.map(names => {
return names.toUpperCase()
});
console.log(newNameArr); // returns: ["TAMIM", "SAKIB", "MUSFIQ"]
const newObject = object.map(item => {
return item.name;
});
console.log(newObject) // return: ["Humayun Ahmed", "Jafar Iqbal", "Ahmed Sofa"]
// But Keep adding [key, values] programmatically SET method is BEST
const rest = new Map();
rest.set('name', 'Hotel Redison');
rest.set('location', 'Dhaka, Bangladesh');
rest.set('categories', ['Deshi', 'Indian', 'Chinese', 'Italiano']).set('open', 11).set('close', 23).set(true, 'We are open :D').set(false, 'We are closed :(');
console.log(rest.get('name')); // returns: Hotel Redison
console.log(rest.get('location')); // returns: Dhaka, Bangladesh
console.log(rest.get(true)); // returns: We are open :D
const time = 21;
console.log(rest.get(time > rest.get('open') && time < rest.get('close'))); // strict mode, all true = true OR 1 false all of them = false
// truthy/falsy value AND conditional true/false, BOTH are different
console.log(rest.has('categories')) // returns: true
Map Iteration
// ============= //
// Map Iteration //
// ============= //
// Scratch to Code this method is BEST
const question = new Map([
['question', 'What is the best programming language in the world?'],
[1, 'C'],
[2, 'Java'],
[3, 'Javascript'],
['correct', 3],
[true, 'Correct'],
[false, 'Try again!']
]);
// Convert Object to Map
const hoursMap = new Map(Object.entries(openingHours));
console.log(hoursMap)
// Quiz app
console.log(question.get('question')); // returns: question
for (const [key, value] of question) {
if (typeof key === 'number') console.log(`Answer ${key}: ${value}`); // returns: 1-3 options
};
const answer = Number(prompt('Your answer'));
console.log(answer); // returns: Input Answer
console.log(question.get(question.get('correct') === answer)); // Correct === Answer
// (===) USE Only for single Input/Output NOT for multiple output.
// Convert Map to Array
console.log([...question]); // Arrays of Arrays
// console.log(question.entries());
console.log([...question.keys()]);
console.log([...question.values()]);
Which Data Structure to Use
Coding Challenge
4. Loop over 'gameEvents' and log each element to the console, marking whether it's in the first half or second half (after 45 min) of the game, like this:
[FIRST HALF] 17: ⚽ GOAL
const gameEvents = new Map([
[17, '⚽ GOAL'],
[36, '� Substitution'],
[47, '⚽ GOAL'],
[61, '� Substitution'],
[64, '� Yellow card'],
[69, '� Red card'],
[70, '� Substitution'],
[72, '� Substitution'],
[76, '⚽ GOAL'],
[80, '⚽ GOAL'],
[92, '� Yellow card'],
]);
// 1
// const events = [...new Set([...gameEvents.values()])]
// Convert Set to Array just use Spread Operator[...] 1 time
const events = [...new Set(gameEvents.values())];
console.log(events) // all events WITHOUT duplicate
// returns: ["⚽ GOAL", "� Substitution", "� Yellow card", "� Red card"]
// 2
gameEvents.delete(64)
console.log(gameEvents) // delete key 64
// 3
// We can write 92 minutes but we want that value dynamically
const times = [...gameEvents.keys()].pop()
// gameEvents.keys() shows us all keys but we need last value dynamically so .pop() delete the last element and give it to us
console.log(times); // find out last value ==> 92
console.log(`An event happened, on average, every ${times/gameEvents.size} minutes`);
// 4
for (const [min, event] of gameEvents) {
const half = min <= 45 ? 'FIRST' : 'SECOND'
console.log(`[${half} HALF] ${min}: ${event}`)
}; // returns:
[FIRST HALF] 17: ⚽ GOAL
[FIRST HALF] 36: � Substitution
[SECOND HALF] 47: ⚽ GOAL
[SECOND HALF] 61: � Substitution
[SECOND HALF] 69: � Red card
[SECOND HALF] 70: � Substitution
[SECOND HALF] 72: � Substitution
[SECOND HALF] 76: ⚽ GOAL
[SECOND HALF] 80: ⚽ GOAL
[SECOND HALF] 92: � Yellow card
Working With Strings
// ==================== //
// Working With Strings //
// ==================== //
const airline = 'TAP Air Portugal';
const plane = 'A320';
console.log(plane[0]); // A
console.log(plane[1]); // 3
console.log(plane[2]); // 2
console.log('B737' [0]); // B
console.log(airline.length); // 16
console.log('B737'.length); // 4
console.log(airline.indexOf('r')); // position at 6
console.log(airline.lastIndexOf('r')); // returns: position at 10
console.log(airline.indexOf('portugal')); // -1
console.log(airline.indexOf('Portugal')); // 8
console.log(airline.slice(4)); // Only Start // Air Portugal
console.log(airline.slice(4, 7)); // End-Beginning // Air
console.log(airline.slice(0, airline.indexOf(' '))) // TAP
console.log(airline.slice(airline.lastIndexOf(' ') + 1)) // Portugal
console.log(airline.slice(0, -1) + 1) // TAP Air Portugal
console.log(airline.slice(-1)) // last Character
const checkMiddleSeat = function (seat) {
// B and E are middle seats
const s = seat.slice(-1);
if (s === 'B' || s === 'E') console.log('You got the middle seat 😖')
else console.log('You got lucky 😃')
};
checkMiddleSeat('11B'); // You got the middle seat 😖
checkMiddleSeat('23C'); // You got lucky 😃
checkMiddleSeat('3E'); // You got the middle seat 😖
console.log(new String('Rafe')) // String {"Rafe"}
// Whenever we call a Method on a String, Javascript convert each character individually to an Object AND when the operation is done convert back to again String.
console.log(typeof new String('Rafe')) // Object
console.log(typeof new String('Rafe').slice(1)) // String
console.log(airline.toLowerCase()); // tap air portugal
console.log(airline.toUpperCase()); // TAP AIR PORTUGAL
// Fix Capitalization in name
const passenger = 'jOnAs' // Should look like this
const passengerLower = passenger.toLocaleLowerCase(); // convert all to lower case
const passengerCorrect = passengerLower[0].toUpperCase() + passengerLower.slice(1); // convert 1st one Upper and rest of lower case
console.log(passengerCorrect)
// Fix Capitalization using function
const fixName = function (name) {
const lowercase = name.toLowerCase();
const correct = lowercase[0].toUpperCase() + lowercase.slice(1);
return correct;
}
console.log(fixName('nUrMohAmmoD'))
// Comparing emails
const email = 'hello@rafe.io';
const loginEmail = ' Hello@Rafe.Io \n';
const lowerEmail = loginEmail.toLowerCase();
const trimmedEmail = lowerEmail.trim();
console.log(trimmedEmail); //hello@rafe.io
// Single line code
const normalizeEmail = loginEmail.toLowerCase().trim();
console.log(normalizeEmail) // hello@rafe.io
console.log(email === normalizeEmail);
// Replacing
const priceGB = '288,97£' // Replace comma(,) and pound sign(£)
const priceUS = priceGB.replace(',', '.').replace('£', '$');
console.log(priceUS); // 288.97$
const announcement = 'All passengers come to boarding door 23. Boarding door 23!'
console.log(announcement.replace('door', 'gate')); // only replace single word
// Replace All()
console.log(announcement.replaceAll('door', 'gate')); // Replace multiple words
// Regular Expression
console.log(announcement.replace(/door/g, 'gate')); // Replace multiple words
// Booleans
const airbus = 'Airbus A320neo';
console.log(airbus.includes('A320')); // true
console.log(airbus.includes('Boeing')); // false
console.log(airbus.startsWith('Air')); // true
console.log(airbus.endsWith('neo')); // true
if (airbus.startsWith('Airbus') && airbus.endsWith('neo')) {
console.log('Part of the NEW Airbus family');
}
// Practice
const checkBaggage = function (items) {
const baggage = items.toLowerCase();
if (baggage.includes('knife') || baggage.includes('gun')) {
console.log('You are NOT allowed on board')
} else {
console.log('You are Welcome!');
}
};
checkBaggage('I have a laptop, some Food and a pocket Knife');
checkBaggage('Socks and camera');
checkBaggage('Got some snacks and gun for protection');
// Split & Join
console.log('A+very+nice+movie'.split('+')); // ["A", "very", "nice", "movie"]
console.log('Nur Mohamod Rafi'.split(' ')); // ["Nur", "Mohamod", "Rafi"]
// Split output Array so Loop is available
const [firstName, lastName] = 'Nur Mohamod Rafi'.split(' ');
console.log(firstName);
console.log(lastName);
// Join('') Method is OPOSITE of Split('') Method
// Join Name 1
const joinName1 = ['Mr.', firstName, lastName.toUpperCase()]
console.log(joinName1); // ['Mr.', 'Nur', 'MOHAMOD']
console.log(...joinName1); // Mr. Nur Mohamod
// Join Name 2
const joinName2 = ['Mr.', firstName, lastName.toUpperCase()].join(' ');
console.log(joinName2); // Mr. Nur MOHAMOD
// Capitalization Multiple Names or Words
const capitalizeName = function (name) {
const names = name.split(' '); // Array output
console.log(names); // ['nur', 'mohamod', 'rafi']
console.log(names[1]);
const namesUpper = [];
for (const n of names) {
// Method 1 toUpperCase + Slice
namesUpper.push(n[0].toUpperCase() + n.slice(1));
// Method 2 Replace
// namesUpper.push(n[0].replace(n[0], n[0].toUpperCase()));
}
console.log(namesUpper.join(' '));
};
capitalizeName('nur mohamod rafi')
// Split('') Output = Array // or USE [...]
// Join Output('') = String
// Padding
const message = 'Go to gate 07';
const padStart = message.padStart(25, '+');
console.log(padStart.padEnd(35, '+'));
console.log(padStart.length);
// Credit Card Masking
const maskCreditCard = function (number) {
const str = String(number);
// OR
// const str = number + ''// => Number + ''(Empthy String) = String
const first = str.slice(0, 4); // first 4
const last = str.slice(-4); // last 4
return last.padStart(str.length, '*') // Except last 4 digit full length of string will covered by * or any characters
}
console.log(maskCreditCard(56869479831659)); // Output: **********1659
// Phone Number Masking
const maskPhoneNumber = function (number) {
const str = String(number);
// NUMBER to STRING Convert Leading 0 Missing
const addZero = str.padStart(11, 0); // Leading 0 problem solved
console.log(addZero);
const first = addZero.slice(0, 3);
const last = addZero.slice(-3);
return first.padEnd(8, '*') + last
}
console.log(maskPhoneNumber(01913093140)); // Output: 019*****140
// Repeat
const message2 = 'Bed weather... All Departures Delayed...'
console.log(message2.repeat(5)); // Repeat 5 times
const planesInline = function(n){
console.log(`There are ${n} planes in line ${'✈'.repeat(n)}`);
};
planesInline(5) // There are 5 planes in line ✈✈✈✈✈
// ================ //
// Coding Chellenge //
// ================ //
/*
Write a program that receives a list of variable names written in underscore_case
and convert them to camelCase.
The input will come from a textarea inserted into the DOM (see code below to
insert the elements), and conversion will happen when the button is pressed.
Test data (pasted to textarea, including spaces):
underscore_case
first_name
Some_Variable
calculate_AGE
delayed_departure
Should produce this output (5 separate console.log outputs):
underscoreCase ✅
firstName ✅✅
someVariable ✅✅✅
calculateAge ✅✅✅✅
delayedDeparture ✅✅✅✅✅
Hints:
§ Remember which character defines a new line in the textarea �
§ The solution only needs to work for a variable made out of 2 words, like a_b
§ Start without worrying about the ✅. Tackle that only after you have the variable
name conversion working �
§ This challenge is difficult on purpose, so start watching the solution in case
you're stuck. Then pause and continue!
*/
/// Solution ///
document.body.append(document.createElement('textarea'));
document.body.append(document.createElement('button'));
document.querySelector('button').addEventListener('click', function () {
const text = document.querySelector('textarea').value;
const rows = text.split('\n'); // '\n' = Enter
for(const [i, row] of rows.entries() ){
const [first, second] = row.toLowerCase().trim().split('_');
const output = (`${first}${second[0].toUpperCase()+second.slice('1')}`)
// toUpperCase() + slice('') or replace(place, item)
console.log(`${output.padEnd(20, ' ')}${'✅'.repeat(i+1)}`);
}
});
// returns
// underscore_case => underscoreCase
// first_name => firstName
// Some_Variable => someVariable
// calculate_AGE => calculateAge
// delayed_departure => delayedDeparture
0 Comments