diff --git a/src/arrays.js b/src/arrays.js index b995952..03e05e4 100644 --- a/src/arrays.js +++ b/src/arrays.js @@ -8,34 +8,86 @@ const each = (elements, cb) => { // Iterates over a list of elements, yielding each in turn to the `cb` function. // This only needs to work with arrays. // based off http://underscorejs.org/#each + for (let i = 0; i < elements.length; i++) { + cb(elements[i], i); + } }; const map = (elements, cb) => { // Produces a new array of values by mapping each value in list through a transformation function (iteratee). // Return the new array. + // elementseach(elements) + for (let i = 0; i < elements.length; i++) { + elements[i] = cb(elements[i]); + } + return elements; }; const reduce = (elements, cb, memo = elements.shift()) => { // Combine all elements into a single value going from left to right. // Elements will be passed one by one into `cb`. // `memo` is the starting value. If `memo` is undefined then make `elements[0]` the initial value. + // each(elements, cb); + // while (!undefined) { + // memo = cb(elements.shift()); + // } + // return memo; + // for (let i = 0; i < elements.length; i++) { + // memo += cb(elements[i]); + // } + // return memo; + // recursive + // if (elements.length === 0){ + // return memo; + // } + // return reduce(elements, cb, memo = elements.shift()) + if (memo === undefined) { + memo = elements[0]; + } + for (let i = 0; i < elements.length; i++) { + // elements[i] = cb(elements[i]); + memo = cb(elements[i]); + } + return memo; }; const find = (elements, cb) => { // Look through each value in `elements` and pass each element to `cb`. // If `cb` returns `true` then return that element. // Return `undefined` if no elements pass the truth test. + for (let i = 0; i < elements.length; i++) { + if (cb(elements[i])) { + return elements[i]; + } + } + return undefined; }; const filter = (elements, cb) => { // Similar to `find` but you will return an array of all elements that passed the truth test // Return an empty array if no elements pass the truth test + const arr = []; + for (let i = 0; i < elements.length; i++) { + if (cb(elements[i])) { + arr.push(elements[i]); + } + } + return arr; }; /* Extra Credit */ const flatten = (elements) => { // Flattens a nested array (the nesting can be to any depth). // Example: flatten([1, [2], [3, [[4]]]]); => [1, 2, 3, 4]; + // const arr = []; + for (let i = 0; i < elements.length; i++) { + if (typeof (elements[i]) === 'object') { + // pop array el, and iterate, and concate elements to original array + const arrayToBeBroken = elements.splice(i, 1)[0]; + return flatten([...elements, ...arrayToBeBroken]); + } + } + return elements; }; /* eslint-enable no-unused-vars, max-len */ diff --git a/src/class.js b/src/class.js index 8276e29..7e00799 100644 --- a/src/class.js +++ b/src/class.js @@ -6,6 +6,16 @@ // for a potential password that will be compared to the `password` property. // Return true if the potential password matches the `password` property. Otherwise return false. +class User { + constructor(options) { + this.email = options.email; + this.password = options.password; + } + + comparePasswords(givenPassword) { + return givenPassword === this.password; + } +} /* eslint-disable no-undef */ // Remove this comment once you write your classes. @@ -19,6 +29,28 @@ // `meow` that should return the string ` meowed!` where `` is the `name` // property set on the Cat instance. +class Animal { + constructor(options) { + this.age = options.age; + } + + growOlder() { + return this.age; + } +} + +class Cat extends Animal { + constructor(options) { + super(); + this.name = options.name; + } + + // super().growOlder(); + meow() { + return `${this.name} meowed!`; + } +} + module.exports = { User, diff --git a/src/closure.js b/src/closure.js index 2d6592f..5ba23aa 100644 --- a/src/closure.js +++ b/src/closure.js @@ -3,6 +3,12 @@ const counter = () => { // Return a function that when invoked increments and returns a counter variable. // Example: const newCounter = counter(); + let count = 0; + const newCounter = () => { + count++; + return count; + }; + return newCounter; // newCounter(); // 1 // newCounter(); // 2 }; @@ -11,11 +17,32 @@ const counterFactory = () => { // Return an object that has two methods called `increment` and `decrement`. // `increment` should increment a counter variable in closure scope and return it. // `decrement` should decrement the counter variable and return it. + let counter = 0; + + const countObj = { + increment: () => { + counter++; + return counter; + } + decrement: () => { + counter = counter - 1; + return counter; + } + }; + + return countObj; }; const limitFunctionCallCount = (cb, n) => { // Should return a function that invokes `cb`. // The returned function should only allow `cb` to be invoked `n` times. + let timesCalled = n; + const inner() => { + if (timesCalled <= timesCalled) { + return cb(); + }; + }; + return inner; }; /* Extra Credit */ diff --git a/src/es6.js b/src/es6.js index eb846ab..583e161 100644 --- a/src/es6.js +++ b/src/es6.js @@ -7,50 +7,53 @@ //---------------- // const, =>, default parameters, arrow functions default return statements using () -var food = 'pineapple'; +const food = 'pineapple'; -var isMyFavoriteFood = function(food) { +const isMyFavoriteFood = (food) => { food = food || 'thousand-year-old egg'; //This sets a default value if `food` is falsey return food === 'thousand-year-old egg'; }; -var isThisMyFavorite = isMyFavoriteFood(food); +const isThisMyFavorite = isMyFavoriteFood(food); //---------------- //const, class, template literals, enhanced object literals (foo: foo, -> foo,) -var User = function(options) { - this.username = options.username; - this.password = options.password; - this.sayHi = function() { - return this.username + ' says hello!'; - }; -} - -var username = 'JavaScriptForever'; -var password = 'password'; - -var me = new User({ - username: username, - password: password, +// const User = (options) { +// this.username = options.username; +// this.password = options.password; +// this.sayHi = () { +// // return this.username + ' says hello!'; +// return `${this.username} says hello!`; +// }; +// } + +const username = 'JavaScriptForever'; +const password = 'password'; + +const me = new User({ + username, + // username: username, + password, + // password: password, }); // ---------------- // let, const, =>, ... (spread operator) -var addArgs = function () { - var sum = 0; - for (var i = 0; i < arguments.length; i++) { +const addArgs = () => { + let sum = 0; + for (let i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; }; -var argsToCb = function (cb) { - var args = Array.prototype.slice.call(arguments); +const argsToCb = (cb) => { + const args = Array.prototype.slice.call(arguments); return cb.apply(null, args.splice(1)); }; -var result = argsToCb(addArgs, 1, 2, 3, 4, 5); //result should be 15 - +const result = argsToCb(addArgs, 1, 2, 3, 4, 5); //result should be 15 +console.log(result) /* eslint-enable */ diff --git a/src/objects.js b/src/objects.js index ba39c6c..1187624 100644 --- a/src/objects.js +++ b/src/objects.js @@ -5,34 +5,61 @@ const keys = (obj) => { // Retrieve all the names of the object's properties. // Return the keys as strings in an array. // Based on http://underscorejs.org/#keys + return Object.keys(obj); }; const values = (obj) => { // Return all of the values of the object's own properties. // Ignore functions // http://underscorejs.org/#values + return Object.values(obj); }; const mapObject = (obj, cb) => { // Like map for arrays, but for objects. Transform the value of each property in turn. // http://underscorejs.org/#mapObject + Object.keys(obj).forEach((currentKey) => { + obj[currentKey] = cb(obj[currentKey]); + }); + return obj; }; const pairs = (obj) => { // Convert an object into a list of [key, value] pairs. // http://underscorejs.org/#pairs + // return Object.enteries(obj); + const arr = []; + keys(obj).forEach((key) => { + arr.push([key, obj[key]]); + }); + return arr; }; const invert = (obj) => { // Returns a copy of the object where the keys have become the values and the values the keys. // Assume that all of the object's values will be unique and string serializable. // http://underscorejs.org/#invert + // can keys be data types other than string? + const newObj = {}; + Object.keys(obj).forEach((currentKey) => { + newObj[obj[currentKey]] = currentKey; + }); + return newObj; }; const defaults = (obj, defaultProps) => { // Fill in undefined properties that match properties on the `defaultProps` parameter object. // Return `obj`. // http://underscorejs.org/#defaults + const defaultPropKeys = keys(defaultProps); + const objectKeys = keys(obj); + + defaultPropKeys.forEach((key) => { + if (!objectKeys.includes(key)) { + obj[key] = defaultProps[key]; + } + }); + return obj; }; /* eslint-enable no-unused-vars */ diff --git a/src/recursion.js b/src/recursion.js index eb65c57..018227a 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -3,14 +3,17 @@ const nFibonacci = (n) => { // fibonacci sequence: 1 2 3 5 8 13 ... // return the nth number in the sequence + return n < 2 ? n : nFibonacci(n - 1) + nFibonacci(n - 2); }; const nFactorial = (n) => { // factorial example: !5 = 5 * 4 * 3 * 2 * 1 // return the factorial of `n` + return n < 2 ? n : n * nFactorial(n - 1); }; /* Extra Credit */ +// how do you decrement or iterate recursively through obj? const checkMatchingLeaves = (obj) => { // return true if every property on `obj` is the same // otherwise return false diff --git a/src/this.js b/src/this.js index 8ea3020..3e1eeb2 100644 --- a/src/this.js +++ b/src/this.js @@ -5,10 +5,18 @@ class User { constructor(options) { // set a username and password property on the user object that is created + this.password = options.password; + this.username = options.username; } // create a method on the User class called `checkPassword` // this method should take in a string and compare it to the object's password property // return `true` if they match, otherwise return `false` + checkPassword(given) { + if (typeof given === 'string') { + return given === this.password; + // throw "given password isnt a string"; + } + } } const me = new User({ username: 'LambdaSchool', password: 'correcthorsebatterystaple' }); @@ -19,13 +27,15 @@ const checkPassword = function comparePasswords(passwordToCompare) { // use `this` to access the object's `password` property. // do not modify this function's parameters // note that we use the `function` keyword and not `=>` + return this.password === passwordToCompare; }; // invoke `checkPassword` on `me` by explicitly setting the `this` context // use .call, .apply, and .bind +// checkPassword(me.this()); // .call - +// checkPassword(me.password); // .apply // .bind diff --git a/test.js b/test.js new file mode 100644 index 0000000..3f6a6a7 --- /dev/null +++ b/test.js @@ -0,0 +1,156 @@ +// class User { +// constructor(options) { +// this.email = options.email; +// this.password = options.password; +// } + +// comparePasswords(givenPassword) { +// return givenPassword === this.password; +// } +// } + +// const nFibonacci = (n) => { +// // fibonacci sequence: 1 2 3 5 8 13 ... +// // return the nth number in the sequence +// return n < 2 ? n : nFibonacci(n - 1) + nFibonacci(n - 2) +// }; +// const nFactorial = (n) => { +// // factorial example: !5 = 5 * 4 * 3 * 2 * 1 +// // return the factorial of `n` +// return n < 2 ? n : n * nFactorial(n-1) +// }; +// console.log(nFactorial(3)); + +const counter = () => { + // Return a function that when invoked increments and returns a counter variable. + // Example: const newCounter = counter(); + let count = 0; + const newCounter = () => { + count++; + return count; + }; + return newCounter; + // const increment = () => count++; + // return increment(); + // newCounter(); // 1 + // newCounter(); // 2 +}; + +newCounter = counter; +console.log(newCounter); +console.log(newCounter); + +// const counterFactory = () => { +// // Return an object that has two methods called `increment` and `decrement`. +// // `increment` should increment a counter variable in closure scope and return it. +// // `decrement` should decrement the counter variable and return it. +// let counter = 0; +// const increment = () => { +// counter++; +// return counter; +// } +// const decrement = () => { +// counter--; +// return counter; +// } +// }; + +// const c = counterFactory(); + + + +// const newObj = {}; +// const obj = {"hello":5,"cake":"good"}; + +// Object.keys(obj).forEach((currentKey) => { +// // console.log(currentKey, obj[currentKey]); +// newObj[obj[currentKey]] = currentKey; +// }); + +// const a = { +// x: 'hi', +// }; +// const b = { +// banana: true, +// bubblegum: false, +// }; + +// const defaults = (obj, defaultProps) => { +// // Fill in undefined properties that match properties on the `defaultProps` parameter object. +// // Return `obj`. +// // http://underscorejs.org/#defaults +// // const defaultPropKeys = keys(defaultProps); +// // const objectKeys = keys(obj); + +// // objectKeys.forEach((key) => { +// // if (defaultPropKeys.includes(key)) { +// // obj[key] = defaultProps[key]; +// // } +// // }); +// // return obj; +// return Object.assign({}, obj, defaultProps); +// }; + +// console.log(defaults(a,b)); +// function reverseCase(str) { +// let newStr = ''; +// str.split("").forEach((c) => { +// if (c === c.toUpperCase()) { +// newStr += c.toLowerCase(); +// } +// if (c === c.toLowerCase()) { +// newStr += c.toUpperCase(); +// } +// }); +// return newStr; +// } + +// function reverseCase(str) { +// return str.split("").forEach((c) => { +// if (c === c.toUpperCase()) { +// // newStr += c.toLowerCase(); +// return c.toLowerCase(); +// } +// if (c === c.toLowerCase()) { +// // newStr += c.toUpperCase(); +// return c.toUpperCase(); +// } +// }).join(''); +// } + +// function reverseCase(str) { +// return str.split("").map((c) => { +// if (c === c.toUpperCase()) { +// return c.toLowerCase(); +// } +// if (c === c.toLowerCase()) { +// return c.toUpperCase(); +// } +// }).join(''); +// } + + +// console.log(reverseCase("HelloWorld")); +// 'hELLO wORLD' to be 'hELLO wORLD' + +// function evenOccurrence(arr) { +// const occurs = {}; +// arr.forEach((num) => { +// if (Object.keys(occurs).includes(num.toString())) { +// occurs[num] = occurs[num] + 1; +// } +// else { +// occurs[num] = 1; +// } +// }); + +// Object.keys(occurs).forEach((key) => { +// if (occurs[key] % 2 === 0) { +// return parseInt(key); +// } +// return null; +// }) +// } + +// console.log(evenOccurrence([1, 7, 2, 4, 5, 6, 8, 9, 6, 4])) +