Skip to content

Commit 3880abb

Browse files
committed
Added Solutions
1 parent a895a97 commit 3880abb

File tree

5 files changed

+148
-2
lines changed

5 files changed

+148
-2
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/arrays.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,85 @@ 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+
13+
for (let i = 0; i < elements.length; i++) {
14+
cb(elements[i], i);
15+
}
1216
};
1317

1418
const map = (elements, cb) => {
1519
// Produces a new array of values by mapping each value in list through a transformation function (iteratee).
1620
// Return the new array.
21+
const mapped = [];
22+
23+
each(elements, (element, index) => {
24+
mapped.push(cb(element, index));
25+
});
26+
27+
return mapped;
1728
};
1829

1930
const reduce = (elements, cb, startingValue) => {
2031
// Combine all elements into a single value going from left to right.
2132
// Elements will be passed one by one into `cb`.
2233
// `startingValue` is the starting value. If `startingValue` is undefined then make `elements[0]` the initial value.
34+
35+
let accumulator = startingValue === undefined ? elements[0] : startingValue;
36+
elements = startingValue === undefined ? elements.slice(1) : elements;
37+
38+
each(elements, (element, index) => {
39+
accumulator = cb(accumulator, element, index);
40+
});
41+
42+
return accumulator;
2343
};
2444

2545
const find = (elements, cb) => {
2646
// Look through each value in `elements` and pass each element to `cb`.
2747
// If `cb` returns `true` then return that element.
2848
// Return `undefined` if no elements pass the truth test.
49+
for (let i = 0; i < elements.length; i++) {
50+
const response = cb(elements[i]);
51+
if (response) {
52+
return elements[i];
53+
}
54+
}
55+
return undefined;
2956
};
3057

3158
const filter = (elements, cb) => {
3259
// Similar to `find` but you will return an array of all elements that passed the truth test
3360
// Return an empty array if no elements pass the truth test
61+
const filtered = [];
62+
each(elements, (element, index) => {
63+
const response = cb(element);
64+
if (response) {
65+
filtered.push(element);
66+
}
67+
});
68+
69+
return filtered;
3470
};
3571

3672
/* Extra Credit */
3773

3874
const flatten = (elements) => {
3975
// Flattens a nested array (the nesting can be to any depth).
4076
// Example: flatten([1, [2], [3, [[4]]]]); => [1, 2, 3, 4];
77+
78+
let elementsLeft = [...elements];
79+
let flatElements = [];
80+
81+
while (elementsLeft.length) {
82+
const item = elementsLeft[0];
83+
elementsLeft = elementsLeft.slice(1);
84+
if (Array.isArray(item)) {
85+
elementsLeft = [...elementsLeft, ...item];
86+
} else {
87+
flatElements = [...flatElements, item];
88+
}
89+
}
90+
return flatElements;
4191
};
4292

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

src/callbacks.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,61 @@
2323
// Write a function called firstItem that passes the first item of the given array to the callback function
2424
// code here
2525

26+
27+
const firstItem = (foods, cb) => {
28+
cb(foods[0]);
29+
};
30+
31+
32+
2633
const foods = ['pineapple', 'mango', 'ribeye', 'curry', 'tacos', 'ribeye', 'mango'];
2734

35+
console.log(foods);
36+
2837
firstItem(foods, (firstItem) => {
2938
console.log(`The first item is ${firstItem}.`);
3039
});
3140

3241
// Write a function called getLength that passes the length of the array into the callback
3342
// code here
3443

44+
const getLength = (foods, cb) => {
45+
cb(foods.length)
46+
}
47+
3548
getLength(foods, (length) => {
3649
console.log(`The length of the array is ${length}.`);
3750
});
3851

3952
// Write a function called last which passes the last item of the array into the callback
4053
// code here
4154

55+
const last = (foods, cb) => {
56+
cb(foods[foods.length - 1])
57+
}
58+
4259
last(foods, (lastItem) => {
4360
console.log(`The last item in the array is ${lastItem}.`);
4461
});
4562

4663
// Write a function called sumNums that adds two numbers and passes the result to the callback
4764
// code here
4865

66+
const sumNums = (x, y, cb) => {
67+
cb(x+y);
68+
}
69+
4970
sumNums(5, 10, (sum) => {
5071
console.log(`The sum is ${sum}.`);
5172
});
5273

5374
// Write a function called multiplyNums that multiplies two numbers and passes the result to the callback
5475
// code here
5576

77+
const multiplyNums = (x, y, cb) => {
78+
cb(x*y)
79+
}
80+
5681
multiplyNums(5, 10, (product) => {
5782
console.log(`The product is ${product}.`);
5883
});
@@ -61,6 +86,10 @@ multiplyNums(5, 10, (product) => {
6186
// Pass true to the callback if it is, otherwise pass false
6287
// code here
6388

89+
const contains = (haystack, needle, cb) => {
90+
return cb(haystack.indexOf(needle) >= 0);
91+
}
92+
6493
contains(foods, 'ribeye', (result) => {
6594
console.log(result ? 'ribeye is in the array' : 'ribeye is not in the array');
6695
});
@@ -69,13 +98,30 @@ contains(foods, 'ribeye', (result) => {
6998
// Pass the array to the callback function. Do not mutate the original array.
7099
// code here
71100

101+
const removeDuplicates = (foods, cb) => {
102+
const noDupes = [];
103+
for(let i = 0; i < foods.length; i++) {
104+
if(noDupes.indexOf(foods[i]) < 0) {
105+
noDupes.push(foods[i])
106+
}
107+
}
108+
cb(noDupes);
109+
}
110+
111+
72112
removeDuplicates(foods, (uniqueFoods) => {
73113
console.log(`foods with duplicates removed: ${uniqueFoods}`);
74114
});
75115

76116
// Write a function called forEach that iterates over the provided array and passes the value and index into the callback.
77117
// code here
78118

119+
const forEach = (foods, cb) => {
120+
for(let i = 0; i < foods.length; i++) {
121+
cb(foods[i], i)
122+
}
123+
}
124+
79125
forEach(foods, (value, index) => {
80126
console.log(`${value} is at index ${index}.`);
81127
});

src/closure.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,37 @@ const counter = () => {
55
// Example: const newCounter = counter();
66
// newCounter(); // 1
77
// newCounter(); // 2
8+
let count = 0;
9+
10+
return () => ++count;
811
};
912

1013
const counterFactory = () => {
1114
// Return an object that has two methods called `increment` and `decrement`.
1215
// `increment` should increment a counter variable in closure scope and return it.
1316
// `decrement` should decrement the counter variable and return it.
17+
let count = 0;
18+
19+
return {
20+
increment: () => ++count,
21+
decrement: () => --count,
22+
};
1423
};
1524

1625
const limitFunctionCallCount = (cb, n) => {
1726
// Should return a function that invokes `cb`.
1827
// The returned function should only allow `cb` to be invoked `n` times.
28+
let invoked = 0;
29+
// error Arrow function used ambiguously with a conditional expression ?!?
30+
// return (...args) => ++invoked <= n ? cb(...args) : null;
31+
return (...args) => {
32+
invoked += 1;
33+
34+
if (invoked <= n) {
35+
return cb(...args);
36+
}
37+
return null;
38+
};
1939
};
2040

2141
/* Extra Credit */
@@ -27,6 +47,16 @@ const cacheFunction = (cb) => {
2747
// If the returned function is invoked with arguments that it has already seen
2848
// then it should return the cached result and not invoke `cb` again.
2949
// `cb` should only ever be invoked once for a given set of arguments.
50+
const cache = {
51+
};
52+
53+
return (...args) => {
54+
const cacheKey = args.toString();
55+
if (!(cacheKey in cache)) {
56+
cache[cacheKey] = cb(...args);
57+
}
58+
return cache[cacheKey];
59+
};
3060
};
3161

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

src/objects.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,31 @@ 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.keys(obj).filter(key => !(typeof obj[key] === 'function')).map(key => obj[key]);
1416
};
1517

16-
const mapObject = (obj, cb) => {
18+
const mapObject = (obj, cb, onlyValues = true) => {
1719
// Like map for arrays, but for objects. Transform the value of each property in turn.
1820
// http://underscorejs.org/#mapObject
21+
// Added an onlyValues param, that you can set to false, if you want to execute callback on said function.
22+
23+
return Object.keys(obj).reduce((transformedObj, key) => {
24+
transformedObj[key] = (onlyValues && obj[key] === 'function') ? obj[key] : cb(obj[key]);
25+
return transformedObj;
26+
}, {});
1927
};
2028

2129
const pairs = (obj) => {
2230
// Convert an object into a list of [key, value] pairs.
2331
// http://underscorejs.org/#pairs
32+
return Object.keys(obj).map(key => [key, obj[key]]);
2433
};
2534

2635
/* Extra credit */
@@ -29,12 +38,23 @@ const invert = (obj) => {
2938
// Returns a copy of the object where the keys have become the values and the values the keys.
3039
// Assume that all of the object's values will be unique and string serializable.
3140
// http://underscorejs.org/#invert
41+
return Object.keys(obj).reduce((transformedObj, key) => {
42+
const value = obj[key];
43+
transformedObj[value] = key;
44+
return transformedObj;
45+
}, {});
3246
};
3347

3448
const defaults = (obj, defaultProps) => {
3549
// Fill in undefined properties that match properties on the `defaultProps` parameter object.
3650
// Return `obj`.
3751
// http://underscorejs.org/#defaults
52+
// return { ...defaultProps, ...obj };
53+
54+
return Object.keys(defaultProps).reduce((transformedObj, key) => {
55+
transformedObj[key] = key in obj ? obj[key] : defaultProps[key];
56+
return transformedObj;
57+
}, obj);
3858
};
3959

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

0 commit comments

Comments
 (0)