Skip to content

Instantly share code, notes, and snippets.

@LGitHub-sprout
Last active June 8, 2023 15:55
Show Gist options
  • Save LGitHub-sprout/c3fa43a5f60773e45f5e103f1dc108c1 to your computer and use it in GitHub Desktop.
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,
// 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