Last active
June 8, 2023 15:55
-
-
Save LGitHub-sprout/c3fa43a5f60773e45f5e103f1dc108c1 to your computer and use it in GitHub Desktop.
Wes Bos Array Cardio I & II: sort, isEmpty check, Constructors (calculator), destructuring,
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://dmitripavlutin.com/javascript-object-destructuring/ | |
// ## Array Cardio Day 2 | |
// https://github.com/wesbos/JavaScript30/blob/master/07%20-%20Array%20Cardio%20Day%202/index-START.html | |
const people = [ | |
{ name: 'Wes', year: 1988 }, | |
{ name: 'Kait', year: 1986 }, | |
{ name: 'Irv', year: 1970 }, | |
{ name: 'Lux', year: 2015 } | |
]; | |
const comments = [ | |
{ text: 'Love this!', id: 523423 }, | |
{ text: 'Super good', id: 823423 }, | |
{ text: 'You are the best', id: 2039842 }, | |
{ text: 'Ramen is my fav food ever', id: 123523 }, | |
{ text: 'Nice Nice Nice!', id: 542328 } | |
]; | |
const people2 = [ | |
'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig', | |
'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving', | |
'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano', | |
'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose', | |
'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank', | |
]; | |
/* | |
Completed | |
*/ | |
// Wes's solution - Destructure example | |
const wesSort = people2.sort((nextItem, item) => { // (a, b) item, nextItem | |
const [aLast, aFirst] = item.split(', '); // split() returns array which can be destructured | |
const [bLast, bFirst] = nextItem.split(', '); | |
return aLast > bLast ? 1 : -1; | |
}); | |
// console.table(wesSort); // works | |
// a = first el for comparison; b = second el for comparison | |
// const customSort = (b, a) => a > b ? 1 : -1; | |
function customSort(a, b) { // (b, a) for asc or (a, b) for desc | |
return a > b ? 1 : -1; | |
} | |
const userSort = people2.sort(customSort); | |
// console.table(userSort); | |
const alphaSort = people2.sort((a, b) => { // reverse sort by changing param order? | |
// console.log('a', a); | |
// console.log('b', b); | |
return b > a ? 1 : -1; // ... or either (-1 : 1) or param order here. | |
}); | |
// console.table(alphaSort); | |
// My solution, but should I explicitly specify sort order or is leaving default ok? | |
console.log('people2 length', people2.length) // 41 people | |
const byLastname = [...people2].sort().map((name) => { | |
const comma = name.indexOf(','); | |
const lastname = name.slice(0, comma); | |
const firstname = name.slice(comma + 2); | |
return `${firstname} ${lastname}`; | |
}); | |
// console.table(byLastname); // works | |
const alpha = people2.sort((a, b) => { | |
if (a > b) return 1; // asc | |
if (a < b) return -1; // desc | |
}); | |
// console.table(alpha); // works - 41 people | |
// console.log(people2.sort()); // sorted but by last, first | |
// Array.prototype.findIndex() | |
// Find the comment with this ID | |
// delete the comment with the ID of 823423 | |
const getIndex = function (arr, id) { | |
return index = arr.findIndex(e => e.id === id); | |
}; | |
console.log('getIndex', getIndex(commentsTemp, 542328)); // getIndex 4 | |
const deleteProperty = function (arr, id) { | |
// const index = getIndex(arr, id); // I prefer this | |
return updateComments = [ // won't mutate array | |
...commentsTemp.slice(0, getIndex(arr, id)), | |
...commentsTemp.slice(getIndex(arr, id) + 1) | |
]; | |
}; | |
console.log('deleteProperty', deleteProperty(commentsTemp, 823423)); // 542328 | |
// Array.prototype.find() | |
// Find is like filter, but instead returns just the one you are looking for | |
// find the comment with the ID of 823423 | |
const getComment = function (arr, id) { | |
return comment = arr.find(e => e.id === id); | |
}; | |
console.log(getComment(commentsTemp, 823423)); // {text: 'Super good', id: 823423} | |
// Some and Every Checks | |
// Array.prototype.some() Is at least one person 19 or older? | |
/* | |
I want a callback func that compares whether AGE (num) is >= to 19. | |
Then use callback in some(callback) to determine whether true/false. | |
*/ | |
const minAge = people.some((person) => { | |
// console.log(2022 - person.year, person); // s/b ea person/object in array | |
const today = new Date().getFullYear(); // current year | |
// console.log(today) // dynamic current year | |
const age = today - person.year; | |
return age >= 19 | |
}); | |
console.log('minAge', minAge); // true | |
// Array.prototype.every() // is everyone 19 or older? Returns a boolean | |
const checkAge = people.every((person) => 19 < (2022 - person.year)); | |
// console.log(checkAge); // false | |
// Wes Bos's Array Cardio 1 | |
// https://github.com/wesbos/JavaScript30/blob/master/04%20-%20Array%20Cardio%20Day%201/index-FINISHED.html | |
const data2 = [ undefined, 'car', 'car', 'truck', 'truck', 'bike', 'walk', undefined, , , 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', undefined, 'car', 'car', 'truck', 'truck', 'bike', 'walk', undefined, , , 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ]; | |
const people = [ | |
'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig', | |
'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving', | |
'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano', | |
'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose', | |
'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank' | |
]; | |
const inventors = [ | |
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 }, | |
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 }, | |
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 }, | |
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 }, | |
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 }, | |
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 }, | |
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 }, | |
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 }, | |
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 }, | |
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 }, | |
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 }, | |
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 } | |
]; | |
// console.log('Original inventors array', inventors) | |
const whales = ['Blue', 'Humpback', 'Beluga']; | |
const exampleNums = [22, 335, 2, 6, 629, 3320, 11, 32, 2, 1, 302, 925]; | |
const exampleNumStrings = ['22', '335', '2', '6', '629', '3320', '11', '32', '2', '1', '302', '925']; | |
const items = [ | |
{ name: 'Edward', value: 21 }, | |
{ name: 'Sharpe', value: 37 }, | |
{ name: 'And', value: 45 }, | |
{ name: 'The', value: -12 }, | |
{ name: 'Magnetic', value: 13 }, | |
{ name: 'Zeros', value: 37 } | |
]; | |
/* | |
Completed | |
*/ | |
// 8. Reduce Exercise | |
// https://www.freecodecamp.org/news/reduce-f47a7da511a9/ | |
const tallyData = data2.reduce((total, item) => { | |
// if property total[item] is 'undefined' (falsy), then create total[item] key/value pair, e.g., 'car: 0, van: 0, ...' | |
// OR if total[item] is 'not falsy' (already set to '0'), then increment total[item] value, 'car: 1, van: 1, ...' | |
// '0, null, undefined, NaN, 'emptyString', false' are all falsy values | |
console.log(total[item]) // 6 undefined (falsy) items | |
total[item] = (total[item] || 0) // sets all props to 0. // increments once set + 1; | |
return total; | |
}, {}); | |
console.log('tallyData', tallyData); // { undefined: 4, car: 10, truck: 6, bike: 4, walk: 4, van:4 } | |
// Sum the instances of each of these (me: like a tally) | |
// https://prateeksurana.me/blog/why-using-object-spread-with-reduce-bad-idea/ | |
// const vehicles = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck']; | |
const vehiclesTally = function (arr) { | |
// return tally = arr.reduce((acc, currVal, i, origArr) => { | |
const tally = arr.reduce((acc, currVal, i, origArr) => { | |
// if (!acc[currVal]) { | |
// acc[currVal] = 1; | |
// } | |
// else acc[currVal]++; | |
// const vehiclesTally = function (arr) { | |
// https://stackoverflow.com/questions/61081565/javascript-computed-properties | |
// Slightly more verbose to separate counter to clarify spread syntax in next example below. | |
// let count = acc[currVal] || 0; | |
// return { | |
// ...acc, | |
// [currVal]: ++count, | |
// }; | |
acc[currVal] = !acc[currVal] ? 1 : ++acc[currVal]; | |
// acc[currVal] = i; | |
return acc; | |
}, {}); | |
return tally; | |
}; | |
console.log(vehiclesTally(vehicles), vehicles.length); // {car: 5, truck: 3, bike: 2, walk: 2, van: 2} 14 | |
// Using spread operator w reduce(). | |
// https://medium.com/swlh/ways-to-use-the-reduce-method-in-javascript-f3d0f309c9e0 | |
// const vehiclesTally = function (arr) { | |
// // Entire object (after arrow) must be wrapped in (parens). | |
// return tally = arr.reduce((acc, currVal) => ({ | |
// // console.log(currVal); // vehicle props: car bike etc | |
// // [currVal] is the key: acc[currVal] is the value | |
// ...acc, [currVal]: (acc[currVal] || 0) + 1, | |
// }), {}); | |
// }; | |
console.log(vehiclesTally(vehicles), vehicles.length); // {car: 5, truck: 3, bike: 2, walk: 2, van: 2} 14 | |
// 7. sort Exercise | |
// Sort the people alphabetically by last name | |
const peopleByLast = people.sort(); | |
console.table(peopleByLast) | |
// 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name | |
// https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris | |
// search TOP discord : 'list of boulevards in paris' | |
// https://www.youtube.com/watch?v=HB1ZC7czKRs&t=705s 11:45 | |
let blvds = Array.from(document.querySelectorAll('.mw-category-group a')); // nodeList(39) to array | |
/* | |
Trying Wes's solution again... didn't work first time bc I wasn't selecting correct element. | |
Need to select element THAT CONTAINS the elements I'm trying to select... duh Lester. | |
*/ | |
// let links = Array.from(blvd.querySelectorAll('a')); // don't need in this example | |
// links is an array => map it to get the textContent | |
// let de = blvds.map(blvd => { | |
// if (blvd.textContent.includes('de')) console.log(blvd.textContent); // logs 12 streeNames, strings | |
// }); | |
// Method Chaining: filter() blvd streetName.textContent to return an A-R-R-A-Y !! | |
let de = blvds.map(blvd => blvd.textContent).filter(streetName => streetName.includes('de')); // returns array | |
// 5. Sort the inventors by years lived | |
const byYearsLived2 = [...inventors].sort((inventor1, inventor2) => { | |
// return (inventor1.passed - inventor1.year) - (inventor2.passed - inventor2.year) // asc | |
return (inventor2.passed - inventor2.year) - (inventor1.passed - inventor1.year) // desc | |
}); | |
console.log(byYearsLived2); | |
// Array.prototype.reduce() | |
// 4. How many years did all the inventors live all together? | |
const totalYears = inventors.reduce( | |
(accumulator, currentVal) => (accumulator + (currentVal.passed - currentVal.year)), | |
0, | |
); | |
console.log('totalYears using reduce()', totalYears); // 861 | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#how_reduce_works_without_an_initial_value | |
// My idea to wrap a reducer in a function, with/without initial value. | |
// Adds all the elements of an array and returns the sum. | |
const array1 = [419, 419, 419, 419]; | |
function reducerWrap(arr) { | |
// const initialValue = 0; // optional initial value variable | |
const sumArr = arr.reduce( | |
(previousValue, currentValue) => previousValue + currentValue, | |
100, // initial value | |
// initialValue, // optional initial value gets returned | |
); | |
return sumArr; | |
} | |
console.log('reducerWrap(array1)', reducerWrap(array1), array1); // 1776 | |
// callbackFn - reduce() without initialValue | |
// accumulator, previousVal, currentVal, index, array | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#how_reduce_works_without_an_initial_value | |
const array1 = [419, 419, 419, 419]; | |
function reducer(accumulator, currentVal, index) { | |
// console.log('index', index) // starts w 2nd item (no initialValue) | |
const total = accumulator + currentVal; | |
return total; | |
} | |
console.log('array1.reduce(reducer)', array1.reduce(reducer)); // 1676 | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#sum_of_values_in_an_object_array | |
const arrOfObjs = [{ x: 1, y: 10 }, { x: 2, y: 10 }, { x: 3, y: 10 }, {x: 4, y: 10 }]; | |
// must supply initialValue with objects | |
const initialVal = 0; | |
const sumObjs = arrOfObjs.reduce( | |
(accumulator, currentVal) => (accumulator + (currentVal.y + currentVal.x)), // currentVal.y), | |
0 // (10 * 10) / 5, // I guess I can do math here | |
); | |
console.log('sumObjs', sumObjs) // 50 | |
// Math.max() - Get largest number from an array | |
// console.log('Math.max', Math.max(20, 3)); // 20 | |
const max = exampleNums.reduce( | |
(accumulator, currentVal) => Math.max(accumulator, currentVal) | |
); | |
// console.log('max', max); // 3320 | |
// Trying to understand reduce() by pushing inventors' years lived into array | |
const getLifespan = (obj) => { | |
const yearsLived = []; | |
for (let item in obj) { | |
const years = obj[item].passed - obj[item].year; | |
yearsLived.push(years) | |
// Loop thru yearsLived to get total years lived? | |
// Isn't ONE idea behind using reduce that there's less chance of mistakes, | |
// and easier to degug? | |
} | |
return yearsLived; // returns array of ea inventor's lifespan | |
} | |
console.log('getLifespan', getLifespan(inventors)); | |
// Array.prototype.sort() | |
// 3. Sort the inventors by birthdate, oldest to youngest | |
const byBirthYear = [...inventors].sort((a, b) => a.year - b.year); | |
// console.log('byBirthYear', byBirthYear); | |
// console.log('original inventors', inventors); | |
console.log('whales', whales.sort()) // functionless | |
// console.log('exampleNumStrings functionless sort', exampleNumStrings.sort()); // strings not sorted correctly | |
// https://stackoverflow.com/questions/8282802/what-do-return-1-1-and-0-mean-in-this-javascript-code#:~:text=No%2C%20%2D1%2C%200%2C,0%20means%20they're%20equivalent. | |
let sortExNums = [...exampleNums].sort((a, b) => { | |
// return a - b; // asc compare nums instead of strings | |
return b - a; // desc compare nums not strings | |
}); | |
// console.log('exampleNums', exampleNums, 'sortExNums', sortExNums); | |
function descOrder(a, b) { // order | |
// console.log(this.length) | |
return b - a; // desc but still strings | |
// return a - b; // asc but still strings | |
} | |
// console.log([...exampleNumStrings].sort(descOrder)) // still strings | |
// https://bobbyhadz.com/blog/javascript-convert-array-of-strings-to-array-of-numbers | |
let sortMixedToNums = [...exampleNumStrings, ...exampleNums].sort(descOrder).map(num => Number(num)); // .map(num => Number(num)) vs. .map(num => num) | |
let sortNumStrings2 = [...exampleNumStrings].sort(descOrder); | |
// console.log('sortMixedToNums', sortMixedToNums) | |
// console.log('sortNumStrings2', sortNumStrings2) // all strings remain strings | |
let sortWhales = [...whales].sort(); | |
// sortWhales = sortWhales.sort(); // unnecessary w chaining | |
const joinWhales = sortWhales.join(' | '); | |
// console.log(whales, joinWhales); | |
// Sorting an object: | |
// console.log(items.sort((a, b) => a.value - b.value)) | |
// console.log('original items', items, [...items].sort((a, b) => a.value - b.value)) | |
const itemsByValue = [...items].sort((a, b) => a.value - b.value); | |
// console.log(itemsByValue); | |
const itemsByName = [...items].sort((a, b) => { | |
const aName = a.name.toLowerCase(); | |
const bName = b.name.toLowerCase(); | |
if (aName < bName) return -1; | |
if (aName > bName) return 1; | |
return 0; | |
}); | |
console.log('itemsByName', itemsByName) | |
exampleNums.forEach((num) => { | |
// console.log(num, String(num).charCodeAt(0)); // ea num's UTF-16 code | |
}) | |
const sortNums = [...exampleNums].sort((a, b) => { | |
// a - b = ? | |
// 22 - 335 = -313 (neg: comes before = asc) | |
// b - a = ? | |
// 335 - 22 = 313 (pos: comes after) | |
// return a - b; // asc | |
return b - a // desc | |
// if (b < a) return 1; // positive comes after in sequence | |
// if (b > a) return -1; // negative comes before (desc) | |
// reverse operators (or a/b) for asc. a or b first doesn't matter. | |
return 0; // remains in same position | |
}); | |
console.log('sortNums', sortNums) | |
const sortNumString = [...exampleNumStrings].sort((a, b) => { | |
return a - b; // ascending - a is smaller than b | |
// if (a < b) return a; // use conditional for alpha comparison | |
// a = Number(a); // doesn't convert to integer | |
// b = Number(b); // doesn't convert to integer | |
// parseInt(a); // also doesn't convert to integer | |
// parseInt(b); // also doesn't convert to integer | |
// return b - a; // descending | |
}); | |
console.log('sortNumString', sortNumString) | |
function concatArr(arr1, arr2) { | |
const arr3 = arr1.concat(arr2); | |
return arr3; | |
} | |
// console.log(concatArr(data2, people)) | |
// Array.prototype.map() | |
// 2. Give us an array of the inventors first and last names | |
// I'm stumped :/ ... so easy I couldn't figure it out, lol. | |
// https://stackoverflow.com/questions/19590865/from-an-array-of-objects-extract-value-of-a-property-as-array | |
function getNames(arr, property1, property2) { | |
let namesArr = []; | |
for (let i = 0; i < arr.length; i++) { | |
namesArr.push(arr[i][property1] + ' ' + arr[i][property2]); // only works w bracket notation | |
} | |
return namesArr; | |
} | |
// const names = getNames(inventors, 'first', 'last') // doesn't work w dot notation (quotes or not) | |
const names = getNames(inventors, 'first', 'last') // only works w bracket notation | |
// console.log('names is array?', Array.isArray(names), names) | |
const inventorNames = inventors.map(el => `${el['first']} ${el['last']}`); // `${el.first} ${el.last}`); | |
// inventors = ['Albert Einstein', 'Isaac Newton', 'Galileo Galilei ... ] | |
// console.log(el, index) // the 12 objects & their indices | |
// console.log(el.length) // undefined | |
// console.log(typeof el) // object not arrays | |
// filter() | |
// const names = arr.filter(name => console.log(name.first)) // ea name (12) logged 12 times :/ | |
// console.log(inventorNames); | |
// 1. Filter the list of inventors for those who were born in the 1500's | |
// function filterInventors(arr) { | |
// // Regular loop | |
// const inventors = []; | |
// for (let i = 0; i < arr.length; i++) { | |
// if (arr[i].year >= 1500 && arr[i].year <= 1599) { | |
// // console.log(arr[i]); // works | |
// inventors.push(arr[i]) | |
// } | |
// } | |
// return inventors; | |
// } | |
// filterInventors(inventors); | |
// console.log(filterInventors(inventors)) | |
// Callback function syntax | |
function filterInventors(el, index, arr) { // don't necess need index, arr | |
// console.log('filterInventors year property', el.year) // returns all years | |
if (el.year >= 1500 && el.year <= 1599) { | |
// console.log('year only: ', el.year) // logs individual elements | |
// return el.year; // entire object, not just year | |
// return arr[index].year // entire object, not just year | |
// return arr[index]['year'] // entire object, not just year | |
// return arr[index] // doesn't need any args apparently | |
return true; // needs return | |
} | |
} | |
// console.log('filtered Inventors', inventors.filter(filterInventors), 'is Array?', Array.isArray()) // false | |
const filteredInventors = inventors.filter(filterInventors); | |
// console.log('filteredInventors', filteredInventors, 'is Array?', Array.isArray(filteredInventors)) // true | |
// Inline callback syntax | |
const filteredInventors2 = inventors.filter(function (el, index, arr) { // don't need index, arr | |
if (el.year >= 1500 && el.year <= 1599) { | |
// console.log('Inventors born in 16th c.:', el.last, el.year, 'passed: ', el.passed) | |
// return 'passed: ' + el.passed; | |
// return true; | |
// return inventors; // nope | |
// return el.year; // nope | |
// return true; // needs return otherwise it's empty array | |
// return arr; // works as long as el, index, arr are passed. | |
} | |
}); | |
// console.log('filteredInventors2', filteredInventors2, 'is Array?', Array.isArray(filteredInventors2)) // true | |
// function callFilteredInventors2() { | |
// console.log('callFilteredInventors2', filteredInventors2, Array.isArray(callFilteredInventors2)) // false | |
// } | |
// callFilteredInventors2(); // works -- returns the 2 filtered objects (not an array btw) | |
// Array.prototype.filter() item.key | |
// 1. Filter the list of inventors for those who were born in the 1500's | |
// Structured like forEach(): arrow func, Callback func, and Inline callback func | |
// https://bobbyhadz.com/blog/javascript-filter-array-of-objects-based-on-property | |
// Arrow function syntax | |
// Wes' solution | |
const inventors1500 = inventors.filter(inventor => inventor.year >= 1500 && inventor.year <= 1599); | |
// My rework of Wes's solution to understand arg use. | |
// const inventors1500 = inventors.filter((inventor, index, arr) => { // el, index, arr | |
// console.log('element', inventor, 'index', index, 'array', arr) | |
// console.log(inventor['first'] + ' ' + inventor['last']); // works | |
// return (inventor['last'] === 'Blodgett') // works | |
// return (inventor.passed > 1900); // works | |
// return (inventor['year'] >= 1500 && inventor['year'] <= 1599); | |
// return (inventor.year >= 1500 && inventor.year <= 1599); // works | |
// }); | |
// console.log('inventors1500', inventors1500, 'is Array?', Array.isArray(inventors1500)) | |
// Arrow syntax: my solution | |
const filteredInventors3 = inventors.filter((el, index, arr) => { | |
// if (arr[index].year >= 1500 && arr[index].year <= 1599) { | |
if (el.year >= 1500 && el.year <= 1599) { | |
// console.log('filter arrow syntax', arr[index]['year']) // 1564, 1571 | |
// filter returns, so I don't need to? | |
return true; // not sure I need a return stmt at all | |
return false; // returns empty array | |
return arr; // returns the same 2 arrays | |
// return arr[index]['year']; // returns the same 2 arrays | |
// return arr[index]; // returns the same 2 arrays | |
// return index; // returns the same 2 arrays | |
// return el; // returns the same 2 arrays | |
// return arr[index].year; // returns the same 2 arrays | |
} | |
}); | |
// console.log('filteredInventors3', filteredInventors3, 'is Array?', Array.isArray(filteredInventors3)) // true | |
// https://masteringjs.io/tutorials/fundamentals/filter-key | |
// Returns the object's filtered key(s) | |
const obj = { firstName: 'Jean-Luc', lastName: 'Picard', age: 59, ship: 'Enterprise' }; | |
const enterpriseCaptain = Object.keys(obj).filter((key) => key.includes('Name')).reduce((acc, key) => { | |
// console.log(Object.assign(cur, { [key]: obj[key] })); | |
return Object.assign(acc, { [key]: obj[key] }); | |
}, {}); | |
console.log(enterpriseCaptain); // {ship: 'Enterprise'} | |
// Noodling w nested arrays (not including objects) | |
// https://stackoverflow.com/questions/51689520/how-to-filter-array-of-arrays | |
const nestedArray = [ | |
['console', 'key', 'value', 'object', 'thing'], | |
['noise', 'console', 'parking', 6], | |
['Gesh', 'Mike', 'console'], | |
['Twyla', 'Hannah', 'Arden', 'console'] | |
]; | |
// console.log(nestedArray) | |
console.log("If there's the data type 'number' in nestedArray, log it."); | |
const nestedArrayItems = nestedArray.filter((arr, index, item) => { | |
// console.log('log arr', arr, 'log index', index, 'log item') // item is ea array in nested | |
// console.log('log item[index]', item[index][index]) | |
// console.log('one', item[index], item[index][index], item[index][index][index]) // incrementing in loop | |
// console.log(item[index].length) | |
// if (item[index].length > 4) console.log(item[index]) | |
// console.log(arr) | |
// console.log(arr.find(item => item === 6)); // undefined 6 undefined undefined | |
arr.find((el, index, arr) => { | |
// if (typeof el === 'number') console.log(`Item of data type "number" is the number ${el} at index ${index}`, 'in the nested array', arr); | |
}); | |
// if (arr.find(digit => digit === 6)) { | |
// console.log('There is a 6') // There is a 6 | |
// } | |
// const num6 = arr.find(item => item === 6) | |
// const num6 = item.find(digit => digit === 6) | |
// console.log('num6', num6) // undefined | |
// return arr.find(item => item === 6); | |
// return true; | |
// return num6 | |
}); | |
// console.log('nestedArrayItems', nestedArrayItems, nestedArray.length) | |
// console.log('nestedArrayItems', nestedArrayItems) | |
// Doesn't work outside the above 'filter' example bc elements are now arrays. | |
nestedArray.find((el, index, arr) => { | |
// console.log(el) // 4 arrays | |
// console.log(index) | |
// console.log(arr) // array of 4 arrays | |
if (typeof el === 'number') console.log('Item of data type "number" is the number', el, 'at index', index, 'in the nested array', arr) | |
}); | |
// https://javascript.info/object | |
// key:value pairs--key is also known as 'identifier' or 'name' | |
const user = [ // an array w one object and 3 items | |
{ | |
name: 'Lester', | |
age: 29, | |
isAdmin: true, | |
'is gay': true, | |
}, | |
'Shivaun', | |
'Twyla', | |
'Toby' | |
]; | |
// 'in' seems to work w array? | |
// console.log("'length' in user", 'length' in user, 'user length', user.length) // 0 zero would be false | |
user[3] = 'David'; | |
// console.log('user array', user) | |
// console.log('user name:', user[0].name) // dot notation calls value for key 'name' | |
// console.log('user age:', user[0].age) | |
// console.log('user isAdmin?', user[0].isAdmin) | |
/* | |
Computed properties and using more complex EXPRESSIONS inside SQUARE BRACKETS | |
https://javascript.info/object#computed-properties | |
*/ | |
// const isAdmin = prompt('Are you an Admin?'); | |
// console.log('isAdmin', isAdmin) | |
// if (isAdmin != false) { | |
// if (isAdmin.toLowerCase() === 'true' || isAdmin.toLowerCase() === 'yes') { | |
// console.log('isAdmin', isAdmin) | |
// console.log('You\'re golden.'); | |
// user[0].name = 'Sexy Lester the Admin.'; | |
// console.log('New user name:', user[0].name); | |
// console.log('user', user) | |
// } else { | |
// console.log('Get outta here!') | |
// delete user[0].name; | |
// console.log('User has been updated;', user) | |
// console.log('Is he gay?', user[0]['is gay']) // use brackets around multi-word keys | |
// console.log('user', user) | |
// } | |
const friends = {}; | |
const enemies = {}; // empty object not associated with anything | |
/* | |
Just defining the key doesn't define/set an object property. | |
After defining a key it should be assigned a value and will be | |
added depending on which object is referenced. | |
*/ | |
friends['out of state'] = 'Mike'; // sets multi-word key to 'out of state' & property value to 'Mike' | |
// friends['sister'] = 'Krista'; // bracket notation: sister is key, krista is value | |
// friends.krista = 'That\'s my sister!'; // dot notation: krista is key | |
// friends['middleSister'] = 'Krista'; | |
const key5 = 'sister'; // unassociated until defined? Sets key but not value | |
enemies[key5] = 'krista'; | |
friends[key5] = 'Krista'; | |
let key1 = 'likes birds'; // sets a multi-word key--notice there's no object associated. | |
friends[key1] = 'Randy'; // sets 'key1' value to 'Randy'--notice there IS an object used | |
// friends['other'] = 'Randy'; // sets 'Randy' value to 'other' key | |
friends.close = 'Olivia'; // set property using dot notation | |
// friends.close = 'Ed'; // overwrites 'close' property w 'Ed' using same key | |
friends.close2 = 'Ed'; // overwrites 'close' property w same key | |
// console.log('close' in friends) // true, close is in 'friends' | |
console.log('friends object', friends) | |
// console.log(friends['out of state']); // use brackets for multi-word keys, not dot notation | |
let key4 = 'acquaintance'; // initializes but doesn't define | |
friends[key4] = 'JoAnne'; | |
const jerk = 'Another jerk'; // not associated until defined? | |
console.log('enemies object', enemies) // empty object | |
enemies.jerk = 'Krishna'; // now it's a property of enemies object | |
// console.log(enemies['jerk']) // brackets needs quotes bc it's a string | |
friends.acquaintance = 'JoAnne'; // define using dot notation | |
// console.log('dot notation', friends.acquaintance) | |
// console.log('bracket notation', friends['acquaintance']) | |
const key3 = 'housemate'; | |
// console.log('log keys', jerk, key1, key4, key3) // seems weird since keys don't log anywhere | |
/* | |
https://javascript.info/object#square-brackets | |
Passing variables ('identifier' or 'name') as 'Key' to access the 'value' | |
*/ | |
// const mutualFriends = prompt('Enter a friend\'s key to see if I know them, too!'); | |
// alert(friends[mutualFriends]) // e.g., friends. | |
const user2 = { | |
name: 'Shivaun', | |
age: 29, | |
} | |
// delete user2.name; // delete property | |
// console.log(user2) | |
// let poop = prompt('What you wanna know \'bout the user?') | |
// delete user2[poop]; // delete age if 'age' entered | |
// console.log(user2) | |
// alert(user2[poop]); | |
/* | |
Use Bracket Notation for more complex property names and variables. | |
Use dot notation for simple, known property names. | |
https://javascript.info/object#computed-properties | |
*/ | |
// const fruit = prompt('Type the kind of fruit you\'d like to purchase.', 'apple'); | |
// const cart = { | |
// [fruit + 'Computers']: 5, // Add 'Computers' to property name. | |
// [fruit]: 1, | |
// } | |
// console.log(fruit, cart[fruit]); | |
// console.log(fruit, cart.kiwiComputers); // Add 'Computers' to call property. | |
let fruit2 = 'apple'; | |
cart2 = { | |
[fruit2 + 'Computers']: 1, | |
} | |
// console.log('Apple computers in stock:', cart2.appleComputers) | |
/* | |
Property Value Shorthand -- return an object | |
https://javascript.info/object#property-value-shorthand | |
write a function 'makeUser' that returns an object | |
object has 2 properties: name, age | |
define 'user' as makeUser() passing the name and age values | |
*/ | |
function makeUser(name, age) { | |
return { | |
name, // shorthand for name: name, | |
age, // shorthand for age: age, | |
looks: 10 // can use regular and shorthand together | |
}; | |
} | |
const user3 = makeUser('Lester', 29); | |
console.log('Return an object in a function', user3) | |
/* | |
There are no limitations on object property names: any strings, symbols | |
and numbers are converted to strings. | |
Zero 0 becomes '0' (string) when used as key. | |
https://javascript.info/object#property-names-limitations | |
*/ | |
const anObject = { | |
somethingElse: "Here's another key/value pair.", | |
0: 'A "zero" as key to this string value.', // 0 gets turned into a string | |
test: false, // NaN // 0 // ' ' // '' // null // undefined | |
3: 'This value "3" comes 2nd after zero even tho it\'s at the end.', | |
nullProperty: null, | |
undefinedProperty: undefined, | |
}; | |
// console.log(anObject.0) // dot notation error | |
// console.log(anObject[0]) // works w brackets | |
// console.log(anObject['0']) // works w brackets | |
// console.log(anObject.somethingElse) | |
anObject.anotherKey = 'anotherKey VALUE'; // set using dot notation | |
// https://javascript.info/object#property-existence-test-in-operator | |
// Check object for 'emptiness', i.e. has properties | |
// console.log('somethingElse' in anObject); // s/b true | |
// console.log(anObject.test, 'Is "test" property in "anObject"?', 'test' in anObject); // undefined | true | |
// must be a property NAME (usually quoted string) but can save a variable as property name | |
const newVar = 'somethingElse'; | |
// console.log('is newVar in anObject?', newVar in anObject) // s/b true | |
// console.log('is nullProperty in anObject?','nullProperty' in anObject) // true | |
// console.log('is undefinedProperty in anObject?','undefined' in anObject) // false | |
for (let key in anObject) { | |
// console.log('the "key" in anObject', key); | |
} | |
for (let value in anObject) { | |
// console.log('"value" in anObject', anObject[value]); // not quote bc it's a variable | |
}; | |
const countryCode = { | |
37: 'Great Britain', | |
49: 'Germany', | |
6: 'Ecuador', | |
}; | |
// console.log('countryCode asc', countryCode) | |
for (let code in countryCode) { | |
// console.log('countryCode', code, typeof code) // strings -- see next example | |
// console.log('Country Code:', code, '| Country:', countryCode[code]); | |
}; | |
const countryCode2 = { | |
// '+' converts to integer | |
'+37': 'Great Britain', | |
'+49': 'Germany', | |
'+6': 'Ecuador', | |
}; | |
// console.log('countryCode2', countryCode2) | |
for (let code in countryCode2) { | |
// console.log('countryCode2', +code, typeof +code) // numbers | |
}; | |
// console.log(countryCode2['+37'], countryCode['37'], countryCode2['Germany']) | |
// console.log('Is "49" in countryCode2?', '+49' in countryCode2) // 'key' in objName syntax | |
// https://www.geeksforgeeks.org/how-to-get-the-size-of-a-javascript-object/#:~:text=We%20can%20get%20size%20of,keys()%20method.&text=Return%20Value%3A%20an%20array%20of,object's%20own%20enumerable%20property%20keys. | |
// https://stackoverflow.com/questions/5223/length-of-a-javascript-object | |
// https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object | |
// https://dmitripavlutin.com/check-if-object-has-property-javascript/ | |
const schedule = {}; | |
const isEmpty = function (obj) { | |
for (key in obj) return false; | |
return true; | |
}; | |
console.log(isEmpty(schedule)); // s/b true - no properties | |
Object.size = function (obj) { | |
let size = 0; | |
let key; | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) size++; | |
} | |
return size; | |
}; | |
schedule['breakfast'] = '7 am'; // changes 'size' of schedule object by adding property | |
// console.log('schedule', Object.size(schedule)); // 1 | |
// console.log(isEmpty(schedule)); // s/b false now | |
// console.log(schedule, Object.keys(schedule)); // {breakfast: '7 am'}, ['breakfast'] | |
// console.log(schedule, Object.values(schedule)); // {breakfast: '7 am'}, ['7 am'] | |
// console.log(Object.keys(schedule).length, Object.values(schedule).length); // 1 1 | |
// https://javascript.info/object#sum-object-properties | |
const staff = { | |
Hannah: 100, | |
Jen: 135, | |
JoAnne: 150, | |
} | |
function sumSalaries(obj) { | |
let sum = 0; | |
for (let key in obj) { | |
sum += obj[key]; | |
} | |
return sum; | |
} | |
// console.log(sumSalaries(staff)); | |
// https://javascript.info/object#multiply-numeric-property-values-by-2 | |
const mainMenu = { | |
width: 200, | |
height: 300, | |
title: 'My Menu', | |
}; | |
// console.log('mainMenu BEFORE', mainMenu) | |
function menuArea(obj) { | |
for (let key in obj) { | |
if (typeof obj[key] === 'number') { | |
obj[key] *= 2; | |
} | |
} | |
} | |
menuArea(mainMenu) | |
// console.log('mainMenu AFTER', mainMenu) | |
// Object Basics | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#object_basics | |
const person = { | |
name: ['Lester', 'Carpenter'], | |
age: 29, | |
// bio: function () { | |
bio() { // also this syntax works | |
// this refers to the object same as person.name or person['age'] | |
this.name.forEach((n) => console.log(`Loop thru object names, ${n} using this.name.forEach`)) | |
console.log(`${this.name[0]} ${this.name[1]} is only ${this.age} and so young, attractive and successful!`); | |
console.log(`${this.name2[0]} ${this.name2[1]}`); // added below | |
}, | |
intro: function () { | |
console.log(`Hello, I'm ${this.name[0]}; I'm tall. It's nice to meet you.`); | |
}, | |
}; | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#setting_object_members | |
person.name2 = ['Krista', 'Carpenter']; // adds new member pair by setting new key of 'name2' | |
person.age = 69 // overwrites existing age | |
person['eyes'] = 'blue'; // new property | |
console.log('person', person) | |
console.log('person eye color', person.eyes); | |
person.farewell = function () { console.log(`See ya! Wouldn't wanna be ya!`) }; | |
person.bio(); | |
person.intro(); | |
person.farewell(); | |
const personInput = document.querySelector('.height'); | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#bracket_notation | |
const person = { | |
name: ['Lester', 'Carpenter'], | |
age: 29, | |
job: 'Gigolo', | |
occupation() { | |
console.log(`'this' keyword refers to the object: this.job = ${this.job}`) | |
}, | |
}; | |
// holding object property in variable - use bracket notation for adding variable | |
function logProperty(propertyName) { | |
// console.log(person.propertyName); // undefined using dot notation | |
console.log(person[propertyName]); // bracket notation works | |
person.occupation(); // | |
} | |
logProperty('name'); | |
// person['height'] = '5feet'; // works | |
person.height = '5feet w dot notation'; // works | |
console.log(person); | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object | |
let prop = 'foo'; | |
o = { | |
[prop]: 'hey', | |
['b' + 'ar']: 'there', | |
}; | |
o.foo = 'you'; | |
console.log('o', o, `${o.foo} ${o.bar}`) | |
// Constructors | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#introducing_constructors | |
function Person(name) { | |
this.name = name; | |
this.introduction = function () { | |
console.log(`Howdy! I'm ${this.name}`); | |
}; | |
} | |
const lester = new Person('Lester'); | |
console.log(lester.name) // Lester | |
lester.introduction(); // Howdy! I'm Lester. | |
const cat = { | |
name: 'Bertie', | |
breed: 'Cymric', | |
color: 'white', | |
greeting: function () { | |
console.log(`Hello, said ${cat.name} the ${cat.breed}`); | |
}, | |
} | |
cat.greeting(); | |
const cat2 = { | |
name: 'Twyla', | |
breed: 'Calico', | |
color: 'multi-colored', | |
greeting: function () { | |
console.log(`Hello, said ${cat2.name} the ${cat2.breed}`); | |
}, | |
} | |
cat2.greeting(); | |
function Cat(name, breed, color) { | |
this.name = name; | |
this.breed = breed; | |
this.color = color; | |
this.greeting = function () { | |
console.log(`Hello, said ${this.name} the ${this.color} ${this.breed}.`); | |
} | |
} | |
const twyla = new Cat('Twyla', 'Calico', 'multi-colored') | |
twyla.greeting(); | |
const toby = new Cat('Toby', 'Tabby', 'orange'); | |
toby.greeting(); | |
// The rest params, for..of, += | |
function sum(...args) { // args is an array | |
let sum = 0; | |
for (let arg of args) sum += arg; | |
// console.log('the args', args, 'is args an array?', Array.isArray(args)) // true | |
return sum; | |
} | |
let x = sum(4, 9, 16, 25, 29, 100, 66, 77); | |
// console.log('x = sum(...)', sum(4, 9, 16, 25, 29, 100, 66, 77)); // x = 326 | |
// console.log('function sum()', sum(9, 9)) // 18 | |
function add(...nums) { | |
let sum = 0; | |
for (let num of nums) sum += num; | |
return sum; | |
} | |
// console.log('add', add(2, 2, 6)) // 10 | |
const add2 = function (...args) { // would arrow func work? | |
let sum = 0; | |
for (let arg of args) { | |
sum += arg; | |
} | |
return sum; | |
}; | |
// console.log('add2(2, 3, 666, 7, 11) no work:', add2(2, 3, 666, 7, 11)); // logs only 1st arg: 2 | |
let z = add(82, 53, 66); // expression initialized as new var, z | |
// console.log('add() reassigned as var z works:', z) // 201 (correct) | |
// Constructors make multiple similar objects, like menu items | |
// https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#introducing_constructors | |
function Person(name, name2, num1, num2) { | |
this.name = name; | |
this.name2 = name2; | |
this.num1 = +num1; | |
this.num2 = +num2; | |
this.intro = function () { | |
console.log(`What's up, ${name2}?`); | |
// return `What's up, ${name2}?`; | |
// return name; | |
}; | |
this.add = function () { | |
return +num1 + +num2; // `${num1} + ${num2}`; | |
}; | |
}; | |
const yano = new Person('Yano', 'Lester', '1', '2'); | |
// console.log(yano.name, yano.name2); // Yano, Lester | |
// console.log(yano.intro()); // What's up, Lester? | |
// console.log('yano.add', yano.add()); // 3 | |
// All args/methods are local to this constructor? | |
function Calculator() { | |
this.methods = { // Basic OBJECT methods to extend: add, subtract | |
// Me: why not make one generic version to extend | |
// since one adds the 'name' and 'func' anyway? | |
"-": (a, b) => a -= b, | |
"+": (a, b) => a += b | |
}; | |
// Split strings, error handling | |
// and RETURNS above 'methods', i.e., call this not methods. | |
this.calculate = function(str) { | |
let split = str.split(' '), | |
a = +split[0], | |
op = split[1], | |
b = +split[2]; | |
// Error handling | |
if (!this.methods[op] || isNaN(a) || isNaN(b)) { | |
return NaN; | |
} | |
// return basic methods after splitting, error handling | |
return this.methods[op](a, b); // [op] is key on method, calls either add, subtract | |
}; | |
// Extendable calculator method - name, func overwrite | |
this.addMethod = function (name, func) { | |
// addMethod EXTENDS 'methods' method above by passing 'name' and 'func' params | |
this.methods[name] = func; | |
// and call 'methods' method w a new arg, 'name' (key) and sets a new value 'func' | |
// which is the expression passed when called (below). | |
}; | |
}; | |
/* Calculator constructor example - objects objects objects | |
https://javascript.info/array-methods#create-an-extendable-calculator | |
1. Basic extendable OBJECT methods: add, subtract. (key/val deliniated for each) | |
subtract key: subtract method value | |
add key: add method value | |
2. Calculate method: de-stringify & var initialization, | |
error handling, return basic methods. | |
3. Extend basic methods. | |
*/ | |
let powerCalc = new Calculator; | |
powerCalc.addMethod("*", (a, b) => a * b); | |
powerCalc.addMethod("/", (a, b) => a / b); | |
powerCalc.addMethod("**", (a, b) => a ** b); | |
powerCalc.addMethod("-", (a, b) => a - b); | |
powerCalc.addMethod("+", (a, b) => a + b); | |
let subtract = powerCalc.calculate('15 - 5'); | |
let add = powerCalc.calculate('15 + 5'); | |
console.log(subtract); // 10 | |
console.log(add); // 20 | |
let divide = powerCalc.calculate("2 / 3"); | |
console.log(divide); // 0.6666666666666666 | |
// Warrior constructor, call() method might not be best practice | |
function Warrior(name, level, weapon) { | |
// this comes first and calls 'name', 'level' props in Hero | |
Hero.call(this, name, level); // this gets hero name and level | |
this.weapon = weapon; | |
// console.log('this', this); // this Warrior {name: 'Sasha', level: 1, weapon: 'FIRE'} | |
}; | |
// A regular function (not a constructor) | |
// Calling object properties using 'this' keyword. | |
function statement() { | |
// Called by - statement.call(sasha); | |
// console.log(this.weapon, 'is a weapon used by the warrior,', this.name); | |
// const stmt = `${this.weapon} is used by the warrior ${this.name}.`; | |
return `${this.weapon} is used by the warrior ${this.name}.`; | |
// return stmt; | |
}; | |
const sasha = new Warrior('Sasha', 2, 'FIRE'); // new instance of Warrior constructor | |
// console.log(sasha); // Warrior {name: 'Sasha', level: 1, weapon: 'FIRE'} | |
// console.log(statement.call(sasha)); // FIRE is used by the warrior Sasha. | |
// A normal object | |
const weapons = { | |
weapon: 'Fire', | |
}; | |
// Constructor - only 'name' and 'level'. Warriors have 'weapon'. | |
function Hero(name, level) { | |
this.name = name; | |
this.level = level; | |
}; | |
const raven = new Hero('Raven', 'Flight'); | |
console.log(raven); // Hero {name: 'Raven', level: 'Flight'} | |
// console.log(statement.call(raven)) | |
// Without 'this' in Hero call above, sasha below won't have name, level props | |
// statement.call(weapons); // Fire is a weapon that should be used thoughtfully. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment