Skip to content

Commit 2a8da43

Browse files
committed
All exercises pass except objects
1 parent c268e18 commit 2a8da43

4 files changed

Lines changed: 127 additions & 4 deletions

File tree

src/arrays.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,77 @@ const each = (elements, cb) => {
99
// This only needs to work with arrays.
1010
// You should also pass the index into `cb` as the second argument
1111
// based off http://underscorejs.org/#each
12+
for (let i = 0; i < elements.length; i++) {
13+
cb(elements[i], i);
14+
}
1215
};
1316

1417
const map = (elements, cb) => {
1518
// Produces a new array of values by mapping each value in list through a transformation function (iteratee).
1619
// Return the new array.
20+
const newArray = [];
21+
for (let i = 0; i < elements.length; i++) {
22+
newArray[i] = cb(elements[i]);
23+
}
24+
return newArray;
1725
};
1826

1927
const reduce = (elements, cb, startingValue) => {
2028
// Combine all elements into a single value going from left to right.
2129
// Elements will be passed one by one into `cb` along with the `startingValue`.
2230
// `startingValue` should be the first argument passed to `cb` and the array element should be the second argument.
2331
// `startingValue` is the starting value. If `startingValue` is undefined then make `elements[0]` the initial value.
32+
if (startingValue === undefined) {
33+
startingValue = elements[0];
34+
for (let i = 1; i < elements.length; i++) {
35+
startingValue = cb(startingValue, elements[i]);
36+
}
37+
} else {
38+
for (let i = 0; i < elements.length; i++) {
39+
startingValue = cb(startingValue, elements[i]);
40+
}
41+
}
42+
return startingValue;
2443
};
2544

2645
const find = (elements, cb) => {
2746
// Look through each value in `elements` and pass each element to `cb`.
2847
// If `cb` returns `true` then return that element.
2948
// Return `undefined` if no elements pass the truth test.
49+
for (let i = 0; i < elements.length; i++) {
50+
if (cb(elements[i])) {
51+
return elements[i];
52+
}
53+
}
54+
return 'undefined';
3055
};
3156

3257
const filter = (elements, cb) => {
3358
// Similar to `find` but you will return an array of all elements that passed the truth test
3459
// Return an empty array if no elements pass the truth test
60+
const filterArray = [];
61+
for (let i = 0; i < elements.length; i++) {
62+
if (cb(elements[i])) {
63+
filterArray.push(elements[i]);
64+
}
65+
}
66+
return filterArray;
3567
};
3668

37-
/* STRETCH PROBLEM */
69+
/* Extra Credit */
3870

3971
const flatten = (elements) => {
4072
// Flattens a nested array (the nesting can be to any depth).
4173
// Example: flatten([1, [2], [3, [[4]]]]); => [1, 2, 3, 4];
74+
const newArr = [];
75+
for (let i = 0; i < elements.length; i++) {
76+
if (Array.isArray(elements[i])) {
77+
elements = elements.concat(elements[i]);
78+
} else if (!Array.isArray(elements[i])) {
79+
newArr.push(elements[i]);
80+
}
81+
}
82+
return newArr;
4283
};
4384

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

src/callbacks.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,34 @@
22

33
const firstItem = (arr, cb) => {
44
// firstItem passes the first item of the given array to the callback function.
5+
cb(arr[0]);
56
};
67

78
const getLength = (arr, cb) => {
89
// getLength passes the length of the array into the callback.
10+
cb(arr.length);
911
};
1012

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

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

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

2328
const contains = (item, list, cb) => {
2429
// contains checks if an item is present inside of the given array/list.
2530
// Pass true to the callback if it is, otherwise pass false.
31+
let result = list.indexOf(item) >= 1 ? true : false;
32+
cb(result);
2633
};
2734

2835
/* STRETCH PROBLEM */
@@ -31,6 +38,8 @@ const removeDuplicates = (array, cb) => {
3138
// removeDuplicates removes all duplicate values from the given array.
3239
// Pass the duplicate free array to the callback function.
3340
// Do not mutate the original array.
41+
const removed = array.filter((item, index, inputArray) => inputArray.indexOf(item) === index);
42+
cb(removed);
3443
};
3544

3645
/* eslint-enable */

src/closure.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,69 @@ const counter = () => {
55
// Example: const newCounter = counter();
66
// newCounter(); // 1
77
// newCounter(); // 2
8+
let count = 0;
9+
10+
return () => {
11+
count++;
12+
return count;
13+
};
814
};
915

1016
const counterFactory = () => {
1117
// Return an object that has two methods called `increment` and `decrement`.
1218
// `increment` should increment a counter variable in closure scope and return it.
1319
// `decrement` should decrement the counter variable and return it.
20+
let count = 0;
21+
22+
return {
23+
increment() {
24+
count++;
25+
return count;
26+
},
27+
28+
decrement() {
29+
count--;
30+
return count;
31+
},
32+
};
1433
};
1534

1635
const limitFunctionCallCount = (cb, n) => {
1736
// Should return a function that invokes `cb`.
1837
// The returned function should only allow `cb` to be invoked `n` times.
38+
let count = 0;
39+
40+
return (...args) => {
41+
count++;
42+
43+
if (count < n) {
44+
return cb(...args);
45+
}
46+
47+
return null;
48+
};
1949
};
2050

21-
/* STRETCH PROBLEM */
51+
/* Extra Credit */
2252

2353
const cacheFunction = (cb) => {
24-
// Should return a funciton that invokes `cb`.
54+
// Should return a function that invokes `cb`.
2555
// A cache (object) should be kept in closure scope.
2656
// The cache should keep track of all arguments have been used to invoke this function.
2757
// If the returned function is invoked with arguments that it has already seen
2858
// then it should return the cached result and not invoke `cb` again.
2959
// `cb` should only ever be invoked once for a given set of arguments.
60+
const cache = {};
61+
62+
return (...args) => {
63+
if (args[0] in cache) {
64+
return cache[args];
65+
}
66+
67+
const newResult = cb(...args);
68+
cache[args] = newResult;
69+
return newResult;
70+
};
3071
};
3172

3273
/* eslint-enable no-unused-vars */
@@ -37,3 +78,4 @@ module.exports = {
3778
cacheFunction,
3879
limitFunctionCallCount,
3980
};
81+

src/objects.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,67 @@ const keys = (obj) => {
55
// Retrieve all the names of the object's properties.
66
// Return the keys as strings in an array.
77
// Based on http://underscorejs.org/#keys
8+
return Object.keys(obj);
89
};
910

1011
const values = (obj) => {
1112
// Return all of the values of the object's own properties.
1213
// Ignore functions
1314
// http://underscorejs.org/#values
15+
return Object.values(obj);
1416
};
1517

1618
const mapObject = (obj, cb) => {
1719
// Like map for arrays, but for objects. Transform the value of each property in turn.
1820
// http://underscorejs.org/#mapObject
21+
const mappedObject = {};
22+
23+
Object.keys(obj).forEach((key) => {
24+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
25+
mappedObject[key] = cb(obj[key]);
26+
}
27+
});
28+
29+
return mappedObject;
1930
};
2031

2132
const pairs = (obj) => {
2233
// Convert an object into a list of [key, value] pairs.
2334
// http://underscorejs.org/#pairs
35+
return Object.entries(obj);
2436
};
2537

26-
/* STRETCH PROBLEMS */
38+
/* Extra credit */
2739

2840
const invert = (obj) => {
2941
// Returns a copy of the object where the keys have become the values and the values the keys.
3042
// Assume that all of the object's values will be unique and string serializable.
3143
// http://underscorejs.org/#invert
44+
const invertedObject = {};
45+
46+
Object.keys(obj).forEach((key) => {
47+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
48+
invertedObject[obj[key]] = key;
49+
}
50+
});
51+
52+
return invertedObject;
3253
};
3354

3455
const defaults = (obj, defaultProps) => {
3556
// Fill in undefined properties that match properties on the `defaultProps` parameter object.
3657
// Return `obj`.
3758
// http://underscorejs.org/#defaults
59+
60+
Object.keys(defaultProps).forEach((prop) => {
61+
if (Object.prototype.hasOwnProperty.call(defaultProps, prop)) {
62+
if (!(prop in obj)) {
63+
obj[prop] = defaultProps[prop];
64+
}
65+
}
66+
});
67+
68+
return obj;
3869
};
3970

4071
/* eslint-enable no-unused-vars */

0 commit comments

Comments
 (0)