Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
575 changes: 131 additions & 444 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"regenerator-runtime": "^0.10.3"
},
"dependencies": {
"eslint-config-airbnb": "^14.1.0"
"eslint-config-airbnb": "^14.1.0",
"yarn-install": "^0.5.1"
}
}
68 changes: 68 additions & 0 deletions src/arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,26 @@ const each = (elements, cb) => {
// This only needs to work with arrays.
// You should also pass the index into `cb` as the second argument
// based off http://underscorejs.org/#each

for (let i = 0; i < elements.length; i++) {
// pass each el and its index in the given array to a cb
cb(elements[i], i);
}
};

const map = (elements, cb) => {
// Do NOT use .map, to complete this function.
// Produces a new array of values by mapping each value in list through a transformation function (iteratee).
// Return the new array.

// hold transformed els into an array
const newArr = [];
for (let i = 0; i < elements.length; i++) {
// transform each el in the given array and push the result to newArr
newArr.push(cb(elements[i]));
}
// output: array containing the transformed els
return newArr;
};

const reduce = (elements, cb, startingValue) => {
Expand All @@ -28,27 +42,81 @@ const reduce = (elements, cb, startingValue) => {
// Elements will be passed one by one into `cb` along with the `startingValue`.
// `startingValue` should be the first argument passed to `cb` and the array element should be the second argument.
// `startingValue` is the starting value. If `startingValue` is undefined then make `elements[0]` the initial value.
// a holds either the starting value or the first el
let a;
if (startingValue) {
a = startingValue;
} else {
// if startingValue is falsy assign a to the first el of the given arr
a = elements.shift();
}
// copy the given arr
const sliced = elements.slice();
for (let i = 0; i < sliced.length; i++) {
// pass a and els of sliced into a cb
// set a to the result of the combining function
a = cb(a, sliced[i]);
}
// output: result of combining all the els in the given arr with cb
return a;
};

const find = (elements, cb) => {
// Do NOT use .includes, to complete this function.
// 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++) {
// iterate over the given arr
if (cb(elements[i])) {
// only return elements for which cb return true
return elements[i];
}
}
};

const filter = (elements, cb) => {
// Do NOT use .filter, to complete this function.
// 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

// hold the els that pass the check in a new array
const result = [];
for (let i = 0; i < elements.length; i++) {
// check if the els pass the test in cb
if (cb(elements[i])) {
result.push(elements[i]);
}
}
// output: array that holds all elements that passed a test in cb
return result;
};

/* STRETCH PROBLEM */

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 flat = [];
function flattenArr(a) {
// base case: el in arr is not an array
if (!Array.isArray(a)) {
flat.push(a);
} else {
// recursive case: el is an array
// iterate over a: go one level into el
a.forEach(el => flattenArr(el));
}
return flat;
}
return flattenArr(elements);
};
// test cases courtesy of FreeCodeCamp
// https://www.freecodecamp.org/challenges/steamroller
// flatten([1, [2], [3, [[4]]]]) returns [1, 2, 3, 4]
// flatten([1, [], [3, [[4]]]]) returns [1, 3, 4]
// flatten([[["a"]], [["b"]]]) returns ["a", "b"]
// flatten([1, {}, [3, [[4]]]]) returns [1, {}, 3, 4]

/* eslint-enable no-unused-vars, max-len */

Expand Down
11 changes: 11 additions & 0 deletions src/callbacks.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
const firstItem = (arr, cb) => {
// firstItem passes the first item of the given array to the callback function.
cb(arr[0]);
};

const getLength = (arr, cb) => {
// getLength passes the length of the array into the callback.
cb(arr.length);
};

const last = (arr, cb) => {
// last passes the last item of the array into the callback.
cb(arr[arr.length - 1]);
};

const sumNums = (x, y, cb) => {
// sumNums adds two numbers (x, y) and passes the result to the callback.
cb(x + y);
};

const multiplyNums = (x, y, cb) => {
// multiplyNums multiplies two numbers and passes the result to the callback.
cb(x * y);
};

const contains = (item, list, cb) => {
// contains checks if an item is present inside of the given array/list.
// Pass true to the callback if it is, otherwise pass false.
// includes() returns true if item is in the given array
// else includes() returns false
cb(list.includes(item));
};

/* STRETCH PROBLEM */
Expand All @@ -29,6 +37,9 @@ const removeDuplicates = (array, cb) => {
// removeDuplicates removes all duplicate values from the given array.
// Pass the duplicate free array to the callback function.
// Do not mutate the original array.
// hold unique elements in a new array
const uniqueEls = Array.from(new Set(array));
return cb(uniqueEls);
};

/* eslint-enable */
Expand Down
38 changes: 36 additions & 2 deletions src/closure.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,52 @@
const counter = () => {
// Return a function that when invoked increments and returns a counter variable.
// Example: const newCounter = counter();
// newCounter(); // 1
// newCounter(); // 2
// initialize a counter to 0
let count = 0;
function newCounter() {
// newCounter increments count by 1 at every function call
count++;
// count is updated and sent to counter scope
return count;
}
newCounter(); // 1
newCounter(); // 2
};

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.
// initialize a counter to 0
let count = 0;
// calculate obj holds increment and decrement functions
const calculate = {
increment() {
// add 1 to count
count++;
return count;
},
decrement() {
// subtract 1 from count
count--;
return count;
}
};
calculate.increment();
calculate.decrement();
};

const limitFunctionCallCount = (cb, n) => {
// Should return a function that invokes `cb`.
// The returned function should only allow `cb` to be invoked `n` times.
function limit() {
// while n is greater than 0 invoke cb
while (n > 0) {
cb();
n--;
}
}
return limit(cb);
};

/* STRETCH PROBLEM */
Expand All @@ -27,6 +60,7 @@ const cacheFunction = (cb) => {
// If the returned function is invoked with arguments that it has already seen
// then it should return the cached result and not invoke `cb` again.
// `cb` should only ever be invoked once for a given set of arguments.

};

/* eslint-enable no-unused-vars */
Expand Down
40 changes: 40 additions & 0 deletions src/objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,35 @@ 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
// output: an array containing the properties of obj
return Object.keys(obj);
};

const values = (obj) => {
// Return all of the values of the object's own properties.
// Ignore functions
// http://underscorejs.org/#values
// output: an array containing the values of obj
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
const props = Object.keys(obj);
const result = {};
for (let i = 0; i < props.length; i++) {
// pass all properties in obj into cb
result[props[i]] = cb(obj[props[i]]);
}
return result;
};

const pairs = (obj) => {
// Convert an object into a list of [key, value] pairs.
// http://underscorejs.org/#pairs
// output: list of key : value pairs in obj
return Object.entries(obj);
};

/* STRETCH PROBLEMS */
Expand All @@ -29,12 +42,39 @@ 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
// method #1: use a loop
// let result = {}; // holds the inverted key value pairs
// let keys = Object.keys(obj);
// let vals = Object.values(obj);
// // iterate over obj's keys
// for (let key of keys) {
// // set props in result to be values of obj
// // values of result will be the properties of obj
// result[obj[key]] = key;
// }
// return result;
// method #2: use array.reduce()
return Object.keys(obj).reduce((a, b) => {
// initial value of a is {}
// set each of obj's keys to a property in a
a[obj[b]] = b;
// a accumulates inverted key:value pairs
return a;
}, {});
// output: an object with obj's keys as values and obj's values as properties
};

const defaults = (obj, defaultProps) => {
// Fill in undefined properties that match properties on the `defaultProps` parameter object.
// Return `obj`.
// http://underscorejs.org/#defaults
const props = Object.keys(defaultProps);
props.forEach((prop) => {
if (obj[prop] === undefined) {
obj[prop] = defaultProps[prop];
}
});
return obj;
};

/* eslint-enable no-unused-vars */
Expand Down
Loading