Section 11: Working with arrays Flashcards
Definition ? Parameters? Application? and Mutate Value? of these methods
- Slice method
- Splice
- Reverse
- Concate
- Join
- At
- Extract partial or create shallow copy of original array - firstIndex (include) - lastIndex (not include). Can take negative number. No mutate
- Extract partial or whole array - firstIndex (include), deleteCount. Can take negative number - Delete last element or take middle elements of array away - Mutated
- Reverse elements in array - No parameter - Mutated
- Concatenate arrays - parameter: second array want to join - - No mutate
- Join elements in array to string - parameter: “separator character” - No mutate
- Retrieve 1 element in array (same as arr[0], arr[4],…). Take negative number (Ex: -1 to get last element in array)
Definition? Parameter? Application? Difference?
forEach & For-of
- forEach is an array’s method. A higher-order function requires a callback function. It doesn’t create a new array and doesn’t return anything. It’s often used when you want to perform some action on each element of the array.
- ( (p1), [p2], [p3] ). P1: Current element in each iteration. P2: index number each iteration. P3: Entire original array
- Print each line of iteration’s result to console or modifying element (if object is an element). Don’t create new array
-
Can’t use
break
orcontinute
on forEach. Can do in for-of
Solve
“Problem: Given an array, positive numbers are deposit, negative numbers are withdraw.
Log to console counter and whether a customer deposit or withdraw, in
- For-of loop
- forEach method
Example “Counter 3 : You withdraw 400”
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
// For-of for (const [i, mov] of movements.entries()) { console.log( `Counter ${i + 1} : You ${mov > 0 ? 'deposit' : 'withdraw'} ${Math.abs( mov )}` ); } // forEach; movements.forEach((mov, i, arr) => console.log( `Counter ${i + 1}: You ${mov > 0 ? 'deposit' : 'withdraw'} ${mov}` ) );
Solve
- Given map and set values. Using method, print to console each element like this
“GBP: Pound sterling”
“EUR: EUR” - What is the difference in parameter of map and set?
const currenciesMap = new Map([
[‘USD’, ‘United States dollar’],
[‘EUR’, ‘Euro’],
[‘GBP’, ‘Pound sterling’],
]);
const currencies = [‘USD’, ‘GBP’, ‘USD’, ‘EUR’, ‘EUR’];
const currenciesUnique = new Set(currencies);
// Map - forEach method currenciesMap.forEach((value, key, map) => console.log(`${key}: ${value}`)); // Set - forEach method currenciesUnique.forEach((value, key, set) => console.log(`${key}: ${value}`));
- Map has key-value pair, so similar to array, P1: value, P2: key (imagine it’s like index position in array).
Set similar to unique array, so P1 = P2 = value
Solve
/*
Julia and Kate are doing a study on dogs. So each of them asked 5 dog owners about their dog’s age, and stored the data into an array (one array for each). For now, they are just interested in knowing whether a dog is an adult or a puppy. A dog is an adult if it is at least 3 years old, and it’s a puppy if it’s less than 3 years old.
Create a function ‘checkDogs’, which accepts 2 arrays of dog’s ages (‘dogsJulia’ and ‘dogsKate’), and does the following things:
- Julia found out that the owners of the FIRST and the LAST TWO dogs actually have cats, not dogs! So create a shallow copy of Julia’s array, and remove the cat ages from that copied array (because it’s a bad practice to mutate function parameters)
(Using 2 ways) - Create an array with both Julia’s (corrected) and Kate’s data
- For each remaining dog, log to the console whether it’s an adult (“Dog number 1 is an adult, and is 5 years old”) or a puppy (“Dog number 2 is still a puppy 🐶”)
- Run the function for both test datasets
HINT: Use tools from all lectures in this section so far 😉
TEST DATA 1: Julia’s data [3, 5, 2, 12, 7], Kate’s data [4, 1, 15, 8, 3]
TEST DATA 2: Julia’s data [9, 16, 6, 8, 3], Kate’s data [10, 5, 6, 1, 4]
GOOD LUCK 😀
*/
const checkDogs = function (dogsJulia, dogsKate) { // 1 - OPTION A // const dogsJuliaCorrected = dogsJulia.slice(1, -2); // 1 - OPTION B const dogsJuliaCorrected = dogsJulia.slice(); dogsJuliaCorrected.splice(0, 1); dogsJuliaCorrected.splice(-2); // 2A const dogs = dogsJuliaCorrected.concat(dogsKate); // 2B // const dogs = [...dogsJuliaCorrected, ...dogsKate]); // 3 dogs.forEach((age, i) => console.log( `Dog number ${i + 1} is ${ age >= 3 ? 'an adult' : 'a puppy' }, and is ${age} years old` ) ); }; checkDogs([3, 5, 2, 12, 7], [4, 1, 15, 8, 3]); checkDogs([9, 16, 6, 8, 3], [10, 5, 6, 1, 4]);
Definition ? Parameters ? of methods
- map
- filter
- reduce
- find
- findIndex
- some
- every
- flat
- flatMap
- sort
- fill
- Array.from()
- map returns a new array containing results of applying operation on all original array elements
- filter returns a new array containing only elements that met test condition
- reduce method reduces all elements to one single value (accumulation). (The returned value from each loop will be updated in parameter 1)
- find method returns first element that met the callback function’s condition
- findIndex returns first index number of an element if that element met callback function’s condition
- some method return true/false if at least one element in array met callback function’s condition
- every method returns true/false if all elements in array met callback function’s condition
- flat method removes nested array and flatterns array. Take number as argument (level of depth)
- flatMap is a combination between flat() and map() but only remove 1-level deep
- sort converts elements to string and sort (so it doesn’t sort numbers by the order we want). Mutate original array. Received a,b as 2 parameters
- fill methods help us fill values to array contaning empty elements or array with predefined elements. P1: value you want to fill, P2: startIndex (include), P3: endIndex (not incl)
- Array.from() use Array() constructor who calling from() method. Create an array from iterable or array-like object. P1: iterable or array-like object (can create empty array with syntax{length: }. P2: map function
map
filter
find
findIndex
some
every
has same parameters
P1: current element
P2: index number
P3: entire array
reduce parameters
P1: accumulator
P2: current element
P3: index number
P4: entire array
Solve
Given movements array, each element is deposit / withdraw amount.
1. Print each element to a new array with string
2. Print each element to each line in console
“Movement 1: You deposited 200”
“Movement 2: You withdraw -400”
- What is similar + difference between these two solutions?
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
// forEach movements.forEach((mov, i) => console.log( `Movements ${i + 1}: You ${mov > 0 ? 'deposited' : 'withdrew'} ${Math.abs( mov )}` ) ); // map movements.map((mov, i) => console.log( `Movements ${i + 1}: You ${mov > 0 ? 'deposited' : 'withdrew'} ${Math.abs( mov )}` ) );
Difference
forEach vs map
Similar: Use to loop over elements in array. Both are higher-order function that requires a callback function. The callback function receives 3 parameters (current element, index, entire array)
Different
1. forEach: Doesn’t create new array and doesn’t return anything. Use when (side-effects):
- Modify object (objects as elements in array, each interation, adding new property to object)
- Manipulate DOM (insertAdjacentHTML, append,…)
- map: return a new array containing results of applying operation on original array elements. Use when you want to transform original array elements to new values
Solve
Given movements array containing deposit and withdraw values in EUR. Using 2-3 ways to
1. Convert values to USD in new array. (1EUR = 1.1USD)
2. Get new array for deposit values and withdraw values
3. Calculate total values of movements
4. Find highest / lowest amount of deposit and withdraw
5. Convert ONLY deposits amount to USD, calculate total value amount
6. Is there any withdraw of 130? yes-no
7. Is there any desposit above 5000? Can we use includes() method?
8. Is all movements are deposits?
9. Sort array in ascending and descending order
const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];
// 1. Convert to USD const eurToUsd = 1.1; const movementsUSD = movements.map(mov => mov * eurToUsd); // 2. Get Deposit & Withdraw const movementsDeposit = movements.filter(mov => mov > 0); const movementsWithdraw = movements.filter(mov => mov < 0); // 3 Total Sum const total = movements.reduce((acc, cur) => acc + cur, 0); // 3840 // 4. Max & Min const maximum = movements.reduce( (acc, cur) => (cur > acc ? cur : acc), movements[0] ); const minimum = movements.reduce( (acc, cur) => (cur < acc ? cur : acc), movements[0] ); console.log(maximum, minimum); // 300 -650 // 4a. Other solution console.log(Math.max(...movements)); // 3000 console.log(Math.min(...movements)); // -650 // 5 const eurToUsd = 1.1; const depositsUSD = movements .filter(mov => mov > 0) .map(mov => mov * eurToUsd) .reduce((acc, cur) => acc + cur, 0); console.log(depositsUSD); // 5522 // 6. => Yes console.log(movements.some(mov => mov === -130)); // same as console.log(movements.includes(-130)); // 7. => No deposit > 5000. Can't use includes() because it requires a value, not condition console.log(movements.some(mov => mov > 5000)); // 8. => No console.log(movements.every(mov => mov > 0)); // 9. const movementsAscending = movements.slice().sort((a, b) => a - b); console.log(movementsAscending); const movementsDescending = movements.slice().sort((a, b) => b - a); console.log(movementsDescending);
Solve
Given data below,
1. find number of deposits of all accounts that at least 1000 using 2 solutions
2. Find the account who has the name of ‘Jessica Davis’ in accounts array (Using 2 solution)
3. create a function to update each account object a new property of username and value is acronym of owner’s name
4. Calculate overall balance of all accounts’ movements in 2 ways
5. Calculate total deposit values of all accounts
6. Create an object containning 2 property deposit and withdraw of all accounts
// Data const account1 = { owner: 'Jonas Schmedtmann', movements: [200, 450, -400, 3000, -650, -130, 70, 1300], interestRate: 1.2, // % pin: 1111, }; const account2 = { owner: 'Jessica Davis', movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30], interestRate: 1.5, pin: 2222, }; const account3 = { owner: 'Steven Thomas Williams', movements: [200, -200, 340, -300, -20, 50, 400, -460], interestRate: 0.7, pin: 3333, }; const account4 = { owner: 'Sarah Smith', movements: [430, 1000, 700, 50, 90], interestRate: 1, pin: 4444, }; const accounts = [account1, account2, account3, account4];
- there are 6 deposits that at least 1000
~~~
// filter + length approach
const numDeposits = accounts
.flatMap(acc => acc.movements)
.filter(mov => mov >= 1000).length;
console.log(numDeposits); // 6
// reduce approach
const numDeposits2 = accounts
.flatMap(acc => acc.movements)
.reduce((acc, cur) => (cur >= 1000 ? ++acc : acc), 0);
console.log(numDeposits2);
2.
const resultAccount = accounts.find(acc => acc.owner === ‘Jessica Davis’);
console.log(resultAccount);
// 3.
const createUsernames = function (accounts) {
accounts.forEach(acc => {
acc.username = acc.owner
.toLowerCase()
.split(‘ ‘)
.map(word => word[0])
.join(‘’);
});
};
createUsernames(accounts);
console.log(accounts);
// 4A
const totalBalance = accounts
.map(acc => acc.movements)
.flat()
.reduce((acc, cur) => acc + cur, 0);
console.log(totalBalance);
// 4B
const totalBalance2 = accounts
.flatMap(acc => acc.movements)
.reduce((acc, cur) => acc + cur, 0);
console.log(totalBalance2);
// 5
const bankDepositSum = accounts
.flatMap(acc => acc.movements)
.filter(mov => mov > 0)
.reduce((acc, cur) => acc + cur, 0);
console.log(bankDepositSum); // 25180
// 6. => {deposit: 25180, withdraw: -7340}
const obj = accounts
.flatMap(acc => acc.movements)
.reduce(
(acc, cur) => {
cur > 0 ? (acc.deposit += cur) : (acc.withdraw += cur);
return acc;
},
{ deposit: 0, withdraw: 0 }
);
console.log(obj);
~~~
Solve
Given dogs’ ages below, calculate average human age of all adult dogs. Know that
- if the dog is <= 2 years old, humanAge = 2 * dogAge. If the dog is > 2 years old, humanAge = 16 + dogAge * 4.
- human at least 18 is considered to be an adult
TEST DATA 1: [5, 2, 4, 1, 15, 8, 3]
TEST DATA 2: [16, 6, 10, 5, 6, 1, 4]
Hint
Let’s go back to Julia and Kate’s study about dogs. This time, they want to convert dog ages to human ages and calculate the average age of the dogs in their study.
Create a function ‘calcAverageHumanAge’, which accepts an arrays of dog’s ages (‘ages’), and does the following things in order:
- Calculate the dog age in human years using the following formula: if the dog is <= 2 years old, humanAge = 2 * dogAge. If the dog is > 2 years old, humanAge = 16 + dogAge * 4.
- Exclude all dogs that are less than 18 human years old (which is the same as keeping dogs that are at least 18 years old)
- Calculate the average human age of all adult dogs (you should already know from other challenges how we calculate averages 😉)
- Run the function for both test datasets
const calcAverageHumanAge = function (ages) { // 1. Result [36, 4, 32, 2, 76, 48, 28] const averageAge = ages .map(age => (age <= 2 ? 2 * age : 16 + age * 4)) .filter(age => age >= 18) .reduce((acc, cur, _, arr) => acc + cur / arr.length, 0); return averageAge; }; console.log(calcAverageHumanAge([5, 2, 4, 1, 15, 8, 3])); // 44 console.log(calcAverageHumanAge([16, 6, 10, 5, 6, 1, 4])); // 47.3
When should we avoid using Chaining Method in array
We should avoid chaining methods that mutate original arrays (splice, reverse method)
Different
findIndex() and indexOf()
- findIndex work with condition
- indexOf only check if array has that value or not
Solve
- Create a new array containing element from 1 -> 100
- Create an array with 100 random dice rolls
// 1
const arr = Array.from({ length: 10 }, (_, i) => i + 1);
console.log(arr);
// 2
const randomDicerolls = Array.from(
{ length: 100 },
() => Math.floor(Math.random() * 6) + 1
);
console.log(randomDicerolls);
Solve
Using finish project ‘Bankist App’. In reality we can only get movements data on display UI. Get all movements in number from UI and store in array
Hint: Attach click event listener on labelWelcome and inside that event, get all movements data
~~~
labelBalance.addEventListener(‘click’, function () {
// OPTION 1: Array.from()
const movementsUI = Array.from(
document.querySelectorAll(‘.movements__value’),
el => Number(el.textContent.replace(‘€’, ‘’))
);
console.log(movementsUI);
// OPTION 2: Spread Operator + Map
const movementsUI2 = […document.querySelectorAll(‘.movements__value’)].map(
el => Number(el.textContent.replace(‘€’, ‘’))
);
console.log(movementsUI2);
});
~~~